Java中是否有类似sizeof的方法?

Ank*_*han 72 java

Java中是否有任何内置方法可以找到任何数据类型的大小?有没有办法找到大小?

Ste*_*n C 59

不.标准Java SE类库中没有这样的方法.

设计人员的观点是Java中不需要它,因为该语言不需要应用程序1知道需要为原始值,对象或具有给定数量元素的数组保留多少空间.

您可能认为sizeof运算符对于需要了解其数据结构占用空间的人员非常有用.但是,您也可以使用Java内存分析器简单可靠地获取此信息,因此不需要sizeof方法.


之前的评论者提出了sizeof(someType)比可读性更高的观点4.如果您接受该可读性论证,那么补救措施就掌握在您手中.只需定义一个这样的类......

public class PrimitiveSizes {
    public static int sizeof(byte b) { return 1; } 
    public static int sizeof(short s) { return 2; }
    // etcetera
}
Run Code Online (Sandbox Code Playgroud)

......并静态导入它......

import static PrimitiveSizes.*;
Run Code Online (Sandbox Code Playgroud)

或者定义一些命名常量; 例如

public static final int SIZE_OF_INT = 4;
Run Code Online (Sandbox Code Playgroud)

或者(Java 8及更高版本)使用Integer.BYTES常量,依此类推.


为什么Java设计人员没有在标准库中实现这一点?我的猜测是:

  • 他们认为没有必要,
  • 他们认为没有足够的需求,而且
  • 他们认为不值得努力.

还有一个问题是,下一个需求将是一种sizeof(Object o)充满技术困难的方法.

上面的关键词是"他们"!

你或我对它的看法并不重要.通过扩展,在评论中讨论这个主题是没有实际意义的.请,只是,不要.


1 - 程序员可能需要知道以便设计节省空间的数据结构.但是,我无法想象为什么在运行时通过方法调用在应用程序代码中需要这些信息.


Ram*_*esh 14

来自JavaWorld文章

一个肤浅的答案是Java没有提供像C的sizeof()这样的东西.但是,让我们考虑为什么Java程序员偶尔会想要它.

AC程序员自己管理大多数数据结构内存分配,而sizeof()对于了解要分配的内存块大小是必不可少的.另外,就像对象初始化而言,像malloc()这样的C内存分配器几乎没有做任何事情:程序员必须设置所有对象字段作为指向其他对象的指针.但是当所有内容都被说明和编码时,C/C++内存分配非常有效.

相比之下,Java对象分配和构造是捆绑在一起的(不可能使用已分配但未初始化的对象实例).如果Java类定义了对其他对象的引用的字段,则在构造时设置它们也很常见.因此,分配Java对象经常会分配许多互连的对象实例:对象图.再加上自动垃圾收集,这非常方便,让您觉得您永远不必担心Java内存分配细节.

当然,这仅适用于简单的Java应用程序.与C/C++相比,等效的Java数据结构往往占用更多的物理内存.在企业软件开发中,接近当今32位JVM上的最大可用虚拟内存是一种常见的可伸缩性约束.因此,Java程序员可以从sizeof()或类似的东西中受益,以密切关注他的数据结构是否变得太大或是否包含内存瓶颈.幸运的是,Java反射允许您很容易地编写这样的工具.

在继续之前,我将免除对本文问题的一些常见但不正确的答案.谬误:不需要Sizeof(),因为Java基本类型的大小是固定的

是的,Java int在所有JVM和所有平台上都是32位,但这只是该数据类型的程序员可感知宽度的语言规范要求.这样的int本质上是一种抽象数据类型,可以通过64位机器上的64位物理内存字进行备份.非原型类型也是如此:Java语言规范没有说明如何在物理内存中对齐类字段,或者在JVM中无法将布尔数组实现为紧凑的位向量.谬误:您可以通过将对象序列化为字节流并查看生成的流长度来测量对象的大小

这不起作用的原因是因为序列化布局只是真正的内存中布局的远程反映.一个简单的方法是查看字符串是如何序列化的:在内存中每个字符串至少为2个字节,但是在序列化形式中,字符串是UTF-8编码的,因此任何ASCII内容都占用了一半的空间

  • "幸运的是,Java反射可以让你很容易地编写这样的工具." 怎么样? (6认同)

Iai*_*oat 11

Java本机访问库通常用于从Java调用本地共享库.在此库中,存在用于确定Java对象大小的方法:

getNativeSize(Class cls)方法及其重载将为大多数类提供大小.

或者,如果您的类继承自JNA的Structure类,则该calculateSize(boolean force)方法将可用.


Mur*_*han 9

你可以像下面那样进行一些操作来获得基元的大小:

public int sizeofInt() {
    int i = 1, j = 0;
    while (i != 0) {
        i = (i<<1); j++;
    }
    return j;
}

public int sizeofChar() {
    char i = 1, j = 0;
    while (i != 0) {
        i = (char) (i<<1); j++;
    }
    return j;
}
Run Code Online (Sandbox Code Playgroud)

  • 使用`i << 8`代替将给出字节数. (5认同)
  • sizeof(在C中)返回字节数,而这些例程将返回位数. (2认同)

Mr *_*der 9

如前所述这里,也有可能通过他们的包装来获得原始类型的大小.

例如,对于long这可能Long.SIZE / Byte.SIZE来自java 1.5(已经由zeodtr提到)或者Long.BYTES来自java 8


snr*_*snr 6

有一种现代方法可以为原始人做到这一点。BYTES类型的使用。

System.out.println("byte " + Byte.BYTES);
System.out.println("char " + Character.BYTES);
System.out.println("int " + Integer.BYTES);
System.out.println("long " + Long.BYTES);
System.out.println("short " + Short.BYTES);
System.out.println("double " + Double.BYTES);
System.out.println("float " + Float.BYTES);
Run Code Online (Sandbox Code Playgroud)

结果是,

byte 1
char 2
int 4
long 8
short 2
double 8
float 4
Run Code Online (Sandbox Code Playgroud)