Java中的实体和模型应该使用Primitive还是Object?
作为 Java 的初学者,我在选择实体或模型类中的变量类型时感到困惑。正如在Java Primitives vs Objects 中提到的,它们都有一些优点和缺点,例如内存使用。但是,我想知道创建实体或模型类时的一般方法。那么,在这种情况下,对于 long、boolean、int 等变量,我应该更喜欢 Primitive 类型还是 Object 类型,如下所示?
public class Student {
private Long id; // long ?
private String name;
private Boolean isGraduated; // boolean ?
private Integer age; // int ?
}
回答
Long和Integer变量的默认值为null。
但是默认值长和INT为0
相比:
如果使用对象:
public class Student {
private Long id; // long ?
private String name;
private Boolean isGraduated; // boolean ?
private Integer age; // int ?
}
id => null
age => null
如果您使用原语:
public class Student {
private long id; // long ?
private String name;
private Boolean isGraduated; // boolean ?
private int age; // int ?
}
id => 0
age => 0
在许多情况下,将 0 作为默认值是令人困惑的,因此在这种情况下使用对象是有意义的。如果对象值为“null”,则您确定该值未初始化。但是如果原始值是“0”,那么就不清楚了:它是一个默认的未初始化值,还是这个值是用“0”初始化的。
我通常更喜欢使用原始类型,除非我需要显式空检查
回答
要么有效
正如您所指出的,原语需要较少的内存。但是对象有优势,特别是在一些需要对象而不是基元的情况下。在某些情况下,可能需要一个原语,尽管自动装箱通常会处理它。当遇到这些情况时,编译器肯定会提醒您。
和Skliar使得一个有效点大约为默认值,而对象没有基元。根据编码情况,两者都可能是一个优势。
请记住,对于您的大部分工作,您不应该担心这一点。这种担忧是过早优化的一个例子。你几乎肯定有更重要的事情要担心。
对于许多常见的业务应用程序来说,内存使用是无关紧要的。为了方便和功能,我自己的默认设置是使用对象。从这些年来我注意到的情况来看,使用似乎相当分裂,有些人倾向于原始类型,有些人倾向于对象。
我对原始对象与对象三思而后的唯一情况是在处理大量数据的循环时可能会调用自动装箱。在这种情况下,仅仅宣布intvsInteger可能会通过避免无意义的拳击而产生重大影响。但是,同样,不要过分担心这一点,因为依赖自动装箱是完全可以接受的,并且通常是最好的策略。
record
Java 16 现在提供记录功能。记录是编写类的一种简短方式,其主要目的是透明和不可变地通信数据。您只需声明成员字段类型和名称。编译器隐式生成构造函数、getter、equals&hashCode和toString方法。
我提到记录只是为了说明这个方便的新特性,可能会变得非常流行,支持对象和原语。所以使用记录不会影响对象对原始决定。
您的示例类将是:
public record Student( Long id , String name , Boolean isGraduated , Integer age ) {}
… 或者:
public record Student( long id , String name , boolean isGraduated , int age ) {}
用法与常规类相同。
Student alice = new Student( 101L , "Alice" , false , 33 ) ;
模糊差异
您应该知道 Oracle 的 Java 团队和相关社区对模糊原语和对象之间的区别很感兴趣。当然,诀窍是在尊重作为 Java 平台标志的极端向后兼容性的同时这样做。
其中一些工作是作为Valhalla 项目的一部分完成的,包括可能向 Java添加值类型。
要了解有关这方面未来可能的方向的更多信息,请参阅 Oracle 的 Brian Goetz 和其他人的演讲。使用您喜欢的搜索引擎搜索“Java JEP 原语”。您会找到 JEP 的链接,例如:
- JEP 401:原始对象(预览版)(2021-05 更新)
- JEP 402:用对象统一基本原语(预览版)(2021-05 更新)
- JEP 218:原始类型的泛型(2017-10 更新)
- JEP 169:值对象(2019-10 更新)