2015-05-29 118 views
1

我有一個類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()方法。

+1

您創建了一個匿名類。 –

+0

這就是所謂的「雙大括號初始化反模式」。你剛剛發現它爲什麼是反模式。 –

+0

我不認爲這個問題是重複的!提問者最後的句子的實際答案是關於內部類的*命名*。這些問題是相關的但不同的。 恐怕我不能添加以下內容作爲答案,因爲問題是關閉的,但是這裏是:內部類不是'Main'類型,但只有它的名字是基於它的,因爲'Main'是封閉的類型。此行爲在[JLS§13.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1)中指定。 – siegi

回答

6

你創建一個從User這裏延伸的anonymous class

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

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

用戶創建一個新的匿名子(外的大括號),然後定義在這個內置的大括號內的初始化塊。爲了清晰起見,人們通常建議避免上述構造(並不是很多人知道它是如何工作的),並且由於您正在創建內部類,因此它將隱式引用外部類。這可能會導致垃圾收集和序列化問題。

話雖如此,我會盡量少用上述(例如,用於在單元測試等,由於其簡潔建立測試集合)

+1

這不是一個* static * initalizer。它是一個普通的「實例」初始值設定項。 –

相關問題