Java中的字节大小枚举

Java中的字节大小枚举,java,android,memory,Java,Android,Memory,我有一个类,其中可能有很多实例(在移动设备上),所以我尝试最小化大小。我的一个字段是“DrawTarget”,它指示绘图操作是被忽略、排队到路径还是被绘制到显示。我希望它需要一个字节或更少,因为只有3个可能的值,但我也希望它是友好的代码,所以我没有硬编码的数字。一种想法是使用如下枚举: public enum DrawTarget { Invisible, Path, Canvas } 但从我读到的内容来看,Java枚举不允许指定内存布局——我不能要求枚举值表示字节大小

我有一个类,其中可能有很多实例(在移动设备上),所以我尝试最小化大小。我的一个字段是“DrawTarget”,它指示绘图操作是被忽略、排队到路径还是被绘制到显示。我希望它需要一个字节或更少,因为只有3个可能的值,但我也希望它是友好的代码,所以我没有硬编码的数字。一种想法是使用如下枚举:

public enum DrawTarget {
    Invisible,
    Path,
    Canvas
}
但从我读到的内容来看,Java枚举不允许指定内存布局——我不能要求枚举值表示字节大小的值——我猜枚举值在Java中最终是整数大小的值

所以我想在枚举中做一个隐式转换操作符。。。这在Java中可能吗?或者是在枚举中实现类似内容的最佳选择:

public static DrawTarget fromValue(byte value) {
    switch (value) {
    case 0:
        return Invisible;
    case 1:
        return Path;
    default:
        return Canvas;
    }
}
然后调用DrawTarget.fromValue,无论我想在哪里访问该值

或者我应该创建一个单字节类,因为显然(从我在这方面的研究中读到的)枚举基本上只是Java中的特殊类

public class DrawTarget {
    public static final byte Invisible = 0;
    public static final byte Path = 1;
    public static final byte Canvas = 2;
}
但是,如果使用最后一个解决方案,如何表示枚举实例的值呢?我仍然需要一种方法来允许“=”操作符接受类的一个静态字段。。。类似于转换构造函数或赋值运算符重载

然而,我怀疑任何类对象,作为引用类型,每个实例将占用超过一个字节的时间。这是真的吗

我猜枚举值在Java中最终是整数大小的值

不,枚举总是Java中的类。因此,如果您有一个类型为
DrawTarget
的字段,则该字段将作为引用-指向
null
DrawTarget
的三个实例之一。(不会有更多的实例了;它不像每次使用时都会创建一个新的
DrawTarget
实例。)

我会使用enum,然后测量内存使用情况-enum在逻辑上是您想要的,因此采用常规方法编写最简单的代码,然后测试性能-而不是猜测瓶颈可能在哪里


在序列化时,您可能希望将值表示为单个字节,然后在反序列化时将其转换回枚举,但除此之外,如果可能,我会在整个代码中使用枚举类型。

除非android有处理枚举引用的特殊方法,对DropTarget的每个引用实际上都会占用内存中的多个字节。枚举是类,枚举实例是对象。因此,对枚举实例的引用占用的内存量与任何其他对象引用相同

我不会太在意它,除非您已经测量到这会导致内存问题,而且减小大小会产生重大影响

您从Enum得到的主要是类型安全性。如果方法将
DropTarget
作为参数,则您(或同事)将无法传递除
DropTarget
的三个实例之一(或null)以外的任何内容。如果改用字节,代码就不那么清晰,任何人都可以传递任何字节值,而不是三个授权字节值


因此,决定哪一个对您最重要,并选择您喜欢的解决方案。

您的类将只包含对枚举的引用。将只创建每个枚举的一个实例

除此之外,考虑使用多态性来实现绘图行为。 如果枚举的值是固定的,则根据每个对象所需的图形行为为其实例化不同的子类


如果该值经常更改,则可以在对象中保留对所需绘图策略的引用。对于不应绘制的对象,请使用空draw()方法引用对象。等等。

在Java enum中,类的实例数和值数一样多。实例是在类(枚举)加载时生成的。在使用枚举变量或枚举属性的每个位置,实际上都使用对现有枚举对象之一的普通引用(初始化枚举后,永远不会创建枚举实例)

这意味着枚举引用的成本与任何其他对象引用的成本一样高,通常为四个字节。这真的,真的,真的很小

  • 您不知道一个字节需要多少内存(真的!记住,低级别内存管理包括大量的填充!),因此任何基于此的“优化”都将失败。在给定的体系结构上,字节字段可能占用与整数字段相同的内存(因为这样可能会更快)

  • 如果您想编写好的Java,请使用enum。真正地不使用enum的唯一好理由是如果您有一个完整的值数组,比如:
    drawTargets[]=new-DrawTarget[100000]

  • 如果您坚持微优化,只需使用普通字节,而忽略枚举<代码>公共静态最终字节某物=1可以用来进行比较(调试时很糟糕)

  • 我已经写了很长一段时间的Android程序,从未见过这样的微优化得到回报。你的案子可能是百万分之一,但我不这么认为


    <>也为了让我们大家都更简单,请考虑在java代码中使用java约定:枚举实例和公共最终静态字段应该是名称<代码>类似于< < />代码>属性>代码>类似于(不<代码> LikeThis < /COD>!).P/>EnUM是特殊的数据类型,而不是类。
    枚举类型是一种特殊的数据类型,它使变量成为一组预定义的常量。变量必须等于为其预定义的值之一。

    并且类引用是整数大小的值,不是吗?@BlueMonkMN:在Android上,我认为是这样。在64位机器上,引用AFAIK的长度为64位,而整数的长度为