如何避免为 java class 中的每个字段调用 this.field
How to avoid calling this.field for every field in a java class
有没有办法避免为 class 中的每个字段调用 this.field?
public class Test {
private String name;
private String email;
public Test(String name, String email) {
// I want to avoid this
this.name = name;
this.email = email;
}
public Test(Test test) {
// Something like this would be perfect, setting both name and email to test
this(test);
}
}
抱歉,避免这种情况的唯一方法是为构造函数参数和 class 字段使用不同的名称。
public Test(String _name, String _email) {
// I want to avoid this
name = _name;
email = _email;
}
也就是说,使用 Java 16+ 的记录语法可能会更好。
只有在名称冲突的情况下才需要使用 this
来解决歧义。
像我这样的一些程序员喜欢经常使用 this.
前缀,而其他人只在必要时才使用。
有关如何避免命名冲突的示例,请参阅 。
使用IDE,卢克
您的 IDE 将生成构造函数、访问器 (getters/setters)、equals
& hashCode
、toString
等。所以你不需要输入 this.
;让机器打字。
使用自定义设置来控制 IDE 是否包含或省略 this.
前缀。
record
您可能有兴趣使用 records 功能,这是 Java 16+ 中的新功能。记录是编写 class 的一种简短方法,其主要目的是透明且不可变地传递数据。
对于一条记录,默认情况下,编译器会隐式写入构造函数、getter、equals
& hashCode
和 toString
。隐式创建的构造函数代表您填充每个成员字段。您编写了该代码的 none。
这是您的 整个 示例 class 写成记录。不需要 this
。您的所有成员字段都是自动分配的。
public record Test ( String name , String email ) {}
谨慎使用记录。他们发明的原因是 而不是 编写更少的代码。原因是提供一种透明传输不可变数据的显式机制,academic-speak 中的“名义元组”。更少的样板代码只是一个很好的 side-effect。我强烈建议阅读 JEP 395 以获得更多解释。
提示:您可以将本答案的两点结合起来。让您的 IDE 从记录开始生成 full-blown class。
- 写一条记录,在括号中列出您的所有会员字段。
- 调用您的 IDE 将
record
转换为 class
。
瞧,你有一个完整的 class,其中包含构造函数、访问器、equals
和 hashCode
,以及 toString
,所有这些都由你以最少的输入量写出.
例如,在 IntelliJ 2022 中,从 light-bulb 图标菜单中选择 将记录转换为 class 会变成:
public record Test ( String name , String email ) {}
…进入这个:
package work.basil.example.recs;
import java.util.Objects;
public final class Test
{
private final String name;
private final String email;
public Test ( String name , String email )
{
this.name = name;
this.email = email;
}
public String name ( ) { return name; }
public String email ( ) { return email; }
@Override
public boolean equals ( Object obj )
{
if ( obj == this ) { return true; }
if ( obj == null || obj.getClass() != this.getClass() ) { return false; }
var that = ( Test ) obj;
return Objects.equals( this.name , that.name ) &&
Objects.equals( this.email , that.email );
}
@Override
public int hashCode ( )
{
return Objects.hash( name , email );
}
@Override
public String toString ( )
{
return "Test[" +
"name=" + name + ", " +
"email=" + email + ']';
}
}
警告:该结果可能不是默认值。我可能更改了 IntelliJ 中的设置。
按照建议,使用记录是最简单的方法:
public record Test (String name, String email) {
}
这就是您所需要的。你会得到什么:
- 接受所有参数的构造函数,顺序与字段列表相同
- 每个字段的方法。这 而不是 以
get
开头。在这种情况下,方法是 name()
和 email()
.
equals
、hashCode
和 toString
使用所有字段的实现。
不需要复制构造函数,因为每个字段都自动为 final。
如果需要,您可以添加额外的构造函数。但是,它们必须 委托给自动生成的构造函数,因为这是设置字段的构造函数。添加其他实用程序方法也可以。
如果需要,您可以向生成的构造函数添加验证。有一种特殊语法允许您省略所有字段名称:
public record Test (String name, String email) {
public Test {
Objects.requireNonNull(name);
Objects.requireNonNull(email);
}
}
作业已为您完成,您也无需输入。
你每次都需要this.x,如果有2个或更多的变量,称为x并且你想调用属性变量x。
使用 this 关键字,指向 class.
的已创建实例(对象)的属性变量
可能有一个名为 x 的属性和一个也称为 x 的局部变量。
有没有办法避免为 class 中的每个字段调用 this.field?
public class Test {
private String name;
private String email;
public Test(String name, String email) {
// I want to avoid this
this.name = name;
this.email = email;
}
public Test(Test test) {
// Something like this would be perfect, setting both name and email to test
this(test);
}
}
抱歉,避免这种情况的唯一方法是为构造函数参数和 class 字段使用不同的名称。
public Test(String _name, String _email) {
// I want to avoid this
name = _name;
email = _email;
}
也就是说,使用 Java 16+ 的记录语法可能会更好。
只有在名称冲突的情况下才需要使用 this
来解决歧义。
像我这样的一些程序员喜欢经常使用 this.
前缀,而其他人只在必要时才使用。
有关如何避免命名冲突的示例,请参阅
使用IDE,卢克
您的 IDE 将生成构造函数、访问器 (getters/setters)、equals
& hashCode
、toString
等。所以你不需要输入 this.
;让机器打字。
使用自定义设置来控制 IDE 是否包含或省略 this.
前缀。
record
您可能有兴趣使用 records 功能,这是 Java 16+ 中的新功能。记录是编写 class 的一种简短方法,其主要目的是透明且不可变地传递数据。
对于一条记录,默认情况下,编译器会隐式写入构造函数、getter、equals
& hashCode
和 toString
。隐式创建的构造函数代表您填充每个成员字段。您编写了该代码的 none。
这是您的 整个 示例 class 写成记录。不需要 this
。您的所有成员字段都是自动分配的。
public record Test ( String name , String email ) {}
谨慎使用记录。他们发明的原因是 而不是 编写更少的代码。原因是提供一种透明传输不可变数据的显式机制,academic-speak 中的“名义元组”。更少的样板代码只是一个很好的 side-effect。我强烈建议阅读 JEP 395 以获得更多解释。
提示:您可以将本答案的两点结合起来。让您的 IDE 从记录开始生成 full-blown class。
- 写一条记录,在括号中列出您的所有会员字段。
- 调用您的 IDE 将
record
转换为class
。
瞧,你有一个完整的 class,其中包含构造函数、访问器、equals
和 hashCode
,以及 toString
,所有这些都由你以最少的输入量写出.
例如,在 IntelliJ 2022 中,从 light-bulb 图标菜单中选择 将记录转换为 class 会变成:
public record Test ( String name , String email ) {}
…进入这个:
package work.basil.example.recs;
import java.util.Objects;
public final class Test
{
private final String name;
private final String email;
public Test ( String name , String email )
{
this.name = name;
this.email = email;
}
public String name ( ) { return name; }
public String email ( ) { return email; }
@Override
public boolean equals ( Object obj )
{
if ( obj == this ) { return true; }
if ( obj == null || obj.getClass() != this.getClass() ) { return false; }
var that = ( Test ) obj;
return Objects.equals( this.name , that.name ) &&
Objects.equals( this.email , that.email );
}
@Override
public int hashCode ( )
{
return Objects.hash( name , email );
}
@Override
public String toString ( )
{
return "Test[" +
"name=" + name + ", " +
"email=" + email + ']';
}
}
警告:该结果可能不是默认值。我可能更改了 IntelliJ 中的设置。
按照建议,使用记录是最简单的方法:
public record Test (String name, String email) {
}
这就是您所需要的。你会得到什么:
- 接受所有参数的构造函数,顺序与字段列表相同
- 每个字段的方法。这 而不是 以
get
开头。在这种情况下,方法是name()
和email()
. equals
、hashCode
和toString
使用所有字段的实现。
不需要复制构造函数,因为每个字段都自动为 final。
如果需要,您可以添加额外的构造函数。但是,它们必须 委托给自动生成的构造函数,因为这是设置字段的构造函数。添加其他实用程序方法也可以。
如果需要,您可以向生成的构造函数添加验证。有一种特殊语法允许您省略所有字段名称:
public record Test (String name, String email) {
public Test {
Objects.requireNonNull(name);
Objects.requireNonNull(email);
}
}
作业已为您完成,您也无需输入。
你每次都需要this.x,如果有2个或更多的变量,称为x并且你想调用属性变量x。 使用 this 关键字,指向 class.
的已创建实例(对象)的属性变量可能有一个名为 x 的属性和一个也称为 x 的局部变量。