靜態方法中使用內部類不能通過new
阿新 • • 發佈:2018-12-26
首先來看一下錯誤程式碼,
public class TraditionalThreadSynchronized {
public static void main(String[] args) {
Outputer outputer = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
Thread.sleep(10 );
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("yinxin");
}
}
}).start();
}
}
class Outputer{
public void output(String name){
int len = name.length();
synchronized(Outputer.class){
for (int i = 0; i < len; i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
}
這裡Outputer是一個內部類,在靜態main方法中new一個Outputer物件是錯誤的。
原因:
首先,內部類是可以直接訪問外部類成員變數的。(new一個物件首先在堆記憶體中建立一個物件,然後在棧記憶體中建立成員變數。)所以必須建立外部類物件,然而,main方法是靜態的,不用建立物件即可訪問外部類的成員變數。 —–內部類要有外部類這個物件,然而main方法沒有建立這個外部類物件所以導致上面程式碼無法執行。
內部類呼叫外部類的成員變數時,是通過編譯器自動為內部類新增一個成員變數, 這個成員變數的型別和外部類的型別相同, 這個成員變數就是指向外部類物件的引用,然後通過這個引用來呼叫外部類成員變數。
改寫
public class TraditionalThreadSynchronized {
public void init(){
Outputer outputer = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("yinxin");
}
}
}).start();
}
public static void main(String[] args) {
new TraditionalThreadSynchronized().init();
}
}
class Outputer{
public void output(String name){
int len = name.length();
synchronized(Outputer.class){
for (int i = 0; i < len; i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
}
通過TraditionalThreadSynchronized物件,呼叫init()方法,這時才能使內部類建立成功。
編譯器自動為內部類的構造方法新增一個引數, 引數的型別是外部類的型別, 在構造方法內部使用這個引數為新增的成員變數賦值;