关于java:为什么这两个看似相同的对象有不同的类类型?

Why do these two apparently identical objects have different class types?

本问题已经有最佳答案,请猛点这里访问。

我有一个类User,只有两个字段:id,name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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类中,我尝试使用两种不同的方法初始化User对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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());
    }
}

然后我可以得到输出

1
2
class test.Main$1
class test.User

有趣的是为什么u类是Main的内部类类型? 但实际上我仍然可以使用u.getId()u.getName()方法。


您正在创建一个从User扩展的匿名类:

1
2
3
4
5
6
User u = new User() { //<-- this open bracket defines a new class
        {
            setId(1l);
            setName("LHuang");
        }
    };

这个

1
2
3
4
5
6
User u = new User() { // here's your derived class
        {             // here's the initialiser block
            setId(1l);
            setName("LHuang");
        }
    };

创建一个新的匿名子类User(外部大括号),然后在其中定义一个初始化块(内部大括号)。

为了清楚起见,通常建议避免使用上述结构(没有多少人知道它是如何工作的),并且因为你正在创建一个内部类,所以它将隐含引用外部类。 这可能会导致垃圾回收和序列化问题。

话虽如此,我会谨慎使用上述内容(例如,由于其简洁性,在单元测试等中设置测试集合)