我有一个(java)类,其中包含大约10个属性,其中许多属性可能会在对象的生命周期内保持未初始化并且未被访问。
因此我正在考虑使用Map<String,Object>
作为属性名称 - &gt;属性值映射而不是很多字段,以节省资源
现在我想知道,如果存在任何官方或非官方规则,何时以及如何决定所描述的可能性之一。在我考虑使用这样的地图之前,一个类应该有多少属性?我应该使用它吗?
提前感谢您对此的建议/意见。
答案 0 :(得分:3)
好的,所以你这样做是为了节省我假设的内存,因为很明显你没有通过访问地图而不是字段来节省CPU资源。所以让我们看看它有多好:(假设没有压缩oops的64位JVM - 这是不切实际但不应该过多地改变结果,你可以自己轻松地计算它)
基本上,java中的字段永远不会占用超过8个字节(引用的字大小)。所以这意味着你的班级有10个字段,假设所有字段都未使用,我们可以保存的最好是8 * 10字节= 80byte。
现在你想用一个HashMap替换它 - 这意味着我们已经用了8个额外的字节。此外,HashMap始终被初始化,因此我们得到以下开销:2个字头+引用+ 3个int + float + 1个数组(2个字开销,4个字节大小,默认为16个引用)占用182 bytes
内存。
我祝贺你拯救了一个惊人的-110 bytes
!
PS:我认为hashset的后备数组的最小可能默认值是2,所以你可以使用它,然后就可以了。但是只要将对象存储在集合中,就会从类使用的Wrapper对象中获得额外的开销。所以真的是个坏主意。
答案 1 :(得分:1)
这不是关于你有多少不同的属性,关于如何使用它们以及需要什么。 Map
将允许更灵活地不具有属性或具有不同实例的不同属性或稍后添加属性(通过向Map
添加内容)。但是如果属性是不同类型String, Integer, Doubles
等,则需要使用类型Map
的{{1}}并在使用它时投射所有值(为您做更多工作)。
答案 2 :(得分:1)
我不认为地图是个好主意。
字段是Type及其subType的属性。想想继承和多态,你怎么能让Map实现OO的那些字符呢?
即使谈论代码风格,也不会使代码更清晰。你如何处理铸造?异常处理?这些代码将远远超过现场声明和getter / setter(如果你有的话)
答案 3 :(得分:0)
我喜欢Map的想法,这些属性是真正可选的和“非必要的”。否则你需要一大堆子类和/或你总是需要在getter中检查null。
至于输入,我经常编写代码传递默认值作为第二个参数,并用它来确定返回类型。 e.g。
int getValue(String key, int defaultValue);
double getValue(String key, double defaultValue);
String getValue(String key, String defaultValue);
调用者,而不是Map,必须知道类型。 YMMV你喜欢这种风格......
但是,对于“必不可少”的属性,我更喜欢真实的字段。