为什么这两个显然相同的对象有不同的类类型?
问题描述:
我有一个类User
,只有两个字段:ID,名称为什么这两个显然相同的对象有不同的类类型?
package test;
public class User {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
然后在Main
类,我试图用两种不同的方法来初始化用户对象:
package test;
/**
* @author lhuang
*/
public class Main {
public static void main(String[] args) {
User u = new User() {
{
setId(1l);
setName("LHuang");
}
};
System.out.println(u.getClass());
User u2 = new User();
u2.setId(1l);
u2.setName("LHuang");
System.out.println(u2.getClass());
}
}
然后我可以得到输出
class test.Main$1
class test.User
有趣的是为什么u类是Main类的内部类类型?但实际上我仍然可以使用u.getId()
和u.getName()
方法。
答
你创建一个从User
这里延伸的anonymous class:
User u = new User() { //<-- this open bracket defines a new class
{
setId(1l);
setName("LHuang");
}
};
答
这
User u = new User() { // here's your derived class
{ // here's the initialiser block
setId(1l);
setName("LHuang");
}
};
用户创建一个新的匿名子(外的大括号),然后定义在这个内置的大括号内的初始化块。为了清晰起见,人们通常建议避免上述构造(并不是很多人知道它是如何工作的),并且由于您正在创建内部类,因此它将隐式引用外部类。这可能会导致垃圾收集和序列化问题。
话虽如此,我会尽量少用上述(例如,用于在单元测试等,由于其简洁建立测试集合)
+1
这不是一个* static * initalizer。它是一个普通的“实例”初始值设定项。 –
您创建了一个匿名类。 –
这就是所谓的“双大括号初始化反模式”。你刚刚发现它为什么是反模式。 –
我不认为这个问题是重复的!提问者最后的句子的实际答案是关于内部类的*命名*。这些问题是相关的但不同的。 恐怕我不能添加以下内容作为答案,因为问题是关闭的,但是这里是:内部类不是'Main'类型,但只有它的名字是基于它的,因为'Main'是封闭的类型。此行为在[JLS§13.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1)中指定。 – siegi