静态方法中使用内部类不能通过new

来源:互联网 发布:div 自动调用js函数 编辑:程序博客网 时间:2024/05/02 13:06

首先来看一下错误代码,

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()方法,这时才能使内部类创建成功。
编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为新增的成员变量赋值;

1 0