Java 14 is out. There are various changes and new features, but what you are interested in is the record that was included as a preview, right? Right? That's why I tried it immediately.
record is a feature included as a preview, so you need to use magic to use it.
java --enable-preview --source 14 RecordSample.java
Also, the content written here is subject to change in the future. (Because it's a preview)
If you use record, a method (getter) to get the field specified at the time of definition is automatically generated.
public class RecordSample {
public static void main(String[] args) {
var person = new Person("Mario", 26);
System.out.println(person.name()); // Mario
System.out.println(person.age()); // 26
}
}
//definition of record
record Person(String name, int age) {}
The point is that the definition of record is very simple. Also, the code on the side that uses record can be written exactly like a conventional class. Also, getters are methods with the same name as fields, not getName (). The setter is not generated. I think it would be nice to be able to choose whether to generate a setter as well, but in general it's better for the object to be immutable, so this may be fine.
Also, using record automatically overrides toString (), equals (), and hashCode () defined in the Object class. Let's look at each example.
public class ToStringSample {
public static void main(String[] args) {
var person = new Person("Mario", 26);
System.out.println(person.toString()); // Person[name=Mario, age=26]
}
}
//definition of record
record Person(String name, int age) {}
it is a good feeling. You won't use it directly, but it's useful when debugging.
public class EqualsSample {
public static void main(String[] args) {
var person1 = new Person("Mario", 26);
var person2 = new Person("Mario", 26);
System.out.println(person1.equals(person2)); // true
person1 = new Person("Mario1", 26);
person2 = new Person("Mario2", 26);
System.out.println(person1.equals(person2)); // false
person1 = new Person("Mario", 26);
person2 = new Person("Mario", 27);
System.out.println(person1.equals(person2)); // false
}
}
//definition of record
record Person(String name, int age) {}
It is true when comparing different objects with the same value (top example), so you can see that they are comparing the field values properly, not the original behavior of the Object class. I've tried different values for specific fields, but of course it's false.
public class HashCodeSample {
public static void main(String[] args) {
var person1 = new Person("Mario", 26);
var person2 = new Person("Mario", 26);
System.out.println(person1.hashCode()); // -1997440586
System.out.println(person2.hashCode()); // -1997440586
}
}
//definition of record
record Person(String name, int age) {}
This is also the same value for another object with the same value. It has been overridden properly.
public class ConstructorSample {
public static void main(String[] args) {
new Person("Mario", -1);
// Exception in thread "main" java.lang.IllegalArgumentException
// at Person.<init>(ConstructorSample.java:11)
// at ConstructorSample.main(ConstructorSample.java:3)
}
}
//definition of record
record Person(String name, int age) {
public Person {
if(age < 0) {
throw new IllegalArgumentException();
}
}
}
It seems that you can also define a constructor. You don't have parentheses. Well, when it comes to writing arguments, you have to write exactly the same thing as above, but if there are parentheses without arguments, it looks like there is an argumentless constructor, so notation without parentheses Probably became. I think it's good. Also, if the access modifier is not public, a compile error will occur.
public class OtherMemberSample {
public static void main(String[] args) {
var person = new Person("Mario", 26);
System.out.println(person.getGender()); // male
}
}
//definition of record
record Person(String name, int age) {
private static String gender = "male";
public String getGender() {
return gender;
}
}
I don't know if I ever want to do that, but I've tried defining other fields and methods. It seems that the field must be static, but it seems that it can be done.
public class ExplicitOverrideSample {
public static void main(String[] args) {
var person = new Person("Mario", 26);
System.out.println(person.toString()); // overrided
System.out.println(person.equals(person)); // false
System.out.println(person.hashCode()); // -1
}
}
//definition of record
record Person(String name, int age) {
@Override
public String toString() {
return "overrided";
}
@Override
public boolean equals(Object o) {
return false;
}
@Override
public int hashCode() {
return -1;
}
}
This is also an example of who does such a thing, but I tried it. Apparently it is more effective to write it explicitly.
Please become a formal function as soon as possible.
Recommended Posts