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

时间:2010-03-03 10:15:02

标签: java

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

15 个答案:

答案 0 :(得分:57)

没有。标准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
}

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

import static PrimitiveSizes.*;

或者定义一些命名常量; e.g。

public static final int SIZE_OF_INT = 4;

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


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

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

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

上面的关键词是“他们”!

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


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

答案 1 :(得分:13)

来自article in JavaWorld

  

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

     

C程序员自己管理大多数数据结构内存分配,   和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是   本质上是一种抽象的数据类型,可以用a来备份   64位计算机上的64位物理内存字。同样的道理   非原型类型:Java语言规范没有说明   类字段应该如何在物理内存或数组中对齐   booleans无法实现为一个紧凑的bitvector   JVM。谬误:您可以通过将对象序列化来测量对象的大小   字节流并查看生成的流长度

     

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

答案 2 :(得分:11)

Java Native Access库通常用于从Java调用本机共享库。在此库中,存在用于确定Java对象大小的方法:

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

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

答案 3 :(得分:8)

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

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;
}

答案 4 :(得分:8)

如上所述here,有可能通过包装器获取原始类型的大小。

e.g。对于long,这可能是来自java 1.5的Long.SIZE / Byte.SIZE(已由zeodtr提及)或Long.BYTES来自java 8

答案 5 :(得分:3)

您可以对Java 1.5中的基本类型使用Integer.SIZE / 8,Double.SIZE / 8等。

答案 6 :(得分:2)

有一种现代方法可以对原始数据进行处理。使用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);

结果是

byte 1
char 2
int 4
long 8
short 2
double 8
float 4

答案 7 :(得分:1)

Instrumentation类有一个getObjectSize()方法,但是你不需要在运行时使用它。检查内存使用情况的最简单方法是使用专门用于帮助您跟踪内存使用情况的分析器。

答案 8 :(得分:1)

我决定在不遵循标准Java约定的情况下创建枚举。也许你喜欢这个。

public enum sizeof {
    ;
    public static final int FLOAT = Float.SIZE / 8;
    public static final int INTEGER = Integer.SIZE / 8;
    public static final int DOUBLE = Double.SIZE / 8;
}

答案 9 :(得分:0)

EhCache提供了一个SizeOf类,它将尝试使用Instrumentation代理,如果代理未加载或无法加载(details here),它将回退到另一种方法。

另见the agent from Heinz Kabutz

答案 10 :(得分:0)

SourceForge.net上有一个类/ jar,它使用Java工具来计算任何对象的大小。以下是说明的链接:java.sizeOf

答案 11 :(得分:0)

试试java.lang.Instrumentation.getObjectSize(Object)。但请注意

  

它返回指定对象占用的存储量的特定于实现的近似值。结果可能包括对象的一些或全部开销,因此对于实现中的比较而不是实现之间的比较是有用的。在单次调用JVM期间,估计值可能会发生变化。

答案 12 :(得分:0)

只需进行一些测试:

/tmp/systemd-private-e8***2-php-fpm.service-3zCfIf/tmp/x/y.mp4

答案 13 :(得分:-1)

我认为它不在java API中。但是大多数具有多个元素的数据类型都有size()方法。我想您可以轻松编写一个函数来自行检查大小吗?

答案 14 :(得分:-1)

是的。.在JAVA中

System.out.println(Integer.SIZE/8);  //gives you 4.
System.out.println(Integer.SIZE);   //gives you 32.

//Similary for Byte,Long,Double....