java内部类学习总结

来源:互联网 发布:淘宝嘉年华妈妈装 编辑:程序博客网 时间:2024/06/05 09:18

java内部类:在一个类的内部定义的类叫内部类。
内部类也会编译成一个独立的.class文件,文件名是 “外部类名 + $ + 内部类名 + .class”。如下代码:

public class OutClass {    class InnerClass{    }}

编译后生成两个.class文件:
这里写图片描述

内部类存在的地方(分类):成员内部类,静态内部类,匿名内部类,方法内部类

public class OutClassTest {    public static void main(String[] args) {        // 外部类实例化        OutClass out = new OutClass();        // 内部类在外部类以外的其他类的实例化        InnerClass inner = out.new InnerClass();        // 外部类类访问内部类变量        out.getInnerClassValue();        // 内部类对同名的外部类成员变量,内部类成员变量,内部类局部变量的访问。        inner.showValue();        // 内部类访问外部类非同名私有变量        inner.getOutClassDifValue();        // 内部类访问外部类私有方法        inner.callOutClassMehod();        // static 内部类的实例化,直接实例化        StaticInnerClass staticClass = new StaticInnerClass();        // static 内部类的实例化,直接实例化        staticClass.showValue();        // 访问static内部类的静态成员方法        StaticInnerClass.show();        // 外部类访问static内部类的私有方法        out.getStaticInnerClassMember();        // 访问匿名内部类的方法        out.callAnonymousClass();        // 访问方法内部类        out.callMethodInnerClass();    }}class OutClass{    public String value = "outclass value";    private String difValue = "outclass difValue";    public static String staticValue = "outclass staticValue";    public OutClass(){        System.out.println("OutClass的构造方法。");    }    public void getInnerClassValue(){        System.out.println("外部类访问内部类变量:" + new InnerClass().name);    }    public static void getStaticInnerClassMember(){        StaticInnerClass.setStaticValue();    }    private void outClassMehod(){        System.out.println("外部类的私有方法。");    }    /**     * 成员内部类     */    class InnerClass{        public String value = "innerClass value";        public String name = "innerClass name";        private static final String staticValue = "内部类的静态final成员变量";        public InnerClass(){            System.out.println("InnerClass的构造方法。");        }        public void showValue(){            String value = "innerClass's method value";            System.out.println("<内外部类同名变量的访问>");            System.out.println("    内部类局部变量的访问:" + value);            System.out.println("    内部类成员变量:" + this.value);            System.out.println("    外部类成员变量:" + OutClass.this.value);        }        public void getOutClassDifValue(){            System.out.println("内部类访问外部类非同名私有变量:" + difValue);        }        public void callOutClassMehod(){            System.out.print("内部类访问外部类的私有方法:");            outClassMehod();        }    }    /**     * 静态内部类     */    static class StaticInnerClass{        public static String staticInnerStaticValue;        static{            System.out.println("\nStaticInnerClass的static块。");        }        public StaticInnerClass(){            System.out.println("StaticInnerClass的构造方法。\nstatic的内部类可以被直接实例化,不用先实例化外部类。");        }        public static void showValue(){            System.out.println("static内部类访问外部类static变量:" + OutClass.staticValue);        }        public static void show(){            System.out.println("外部类访问静态内部类的静态方法。");        }        private static void setStaticValue(){            staticInnerStaticValue = "staticInnerStaticValue";            System.out.println("静态内部类的静态成员变量:" + staticInnerStaticValue);        }    }    private void anonymousClass(AnonymousInnerClass anonymousClass){        anonymousClass.say();    }    public void callAnonymousClass(){        /**         * 匿名内部类         */        anonymousClass(new AnonymousInnerClass(){            public void AnonymousInnerClass(){                System.out.println("\n匿名内部类没有构造方法!");            }            @Override            public void say() {                AnonymousInnerClass();                System.out.println("匿名类的方法。匿名类需要借助接口完成。");            }        });    }    public void callMethodInnerClass(){        /**         * 方法内部类         */        class MetohdInnerClass{            public MetohdInnerClass(){                System.out.println("\nMetohdInnerClass的构造器。");            }            public void speek(){                System.out.println("方法内部类访问外部类私有变量:" + difValue);            }        }        new MetohdInnerClass().speek();    }}interface AnonymousInnerClass{    void say();}

上面代码的输出结果:

OutClass的构造方法。InnerClass的构造方法。InnerClass的构造方法。外部类访问内部类变量:innerClass name<内外部类同名变量的访问>    内部类局部变量的访问:innerClass's method value    内部类成员变量:innerClass value    外部类成员变量:outclass value内部类访问外部类非同名私有变量:outclass difValue内部类访问外部类的私有方法:外部类的私有方法。StaticInnerClass的static块。StaticInnerClass的构造方法。static的内部类可以被直接实例化,不用先实例化外部类。static内部类访问外部类static变量:outclass staticValue外部类访问静态内部类的静态方法。静态内部类的静态成员变量:staticInnerStaticValue匿名内部类没有构造方法!匿名类的方法。匿名类需要借助接口完成。MetohdInnerClass的构造器。方法内部类访问外部类私有变量:outclass difValue

结果说明以下几个问题:

  1. 成员内部类
    成员内部类可以直接访问外部类的任意的成员变量或方法。外部类访问内部类的变量或方法要实例化内部类。
    内部类访问同名变量
    value, this.value, OutClass.this.value(外部类的静态成员变量直接OutClass.value)
    外部类以外的类访问成员内部类时,需要先实例化外部类,再实例化内部类。
  2. 静态内部类
    感觉和其他静态类使用效果一样,外部类以外的其他类调用静态内部类时可以直接new出静态内部类。也可以直接用静态内部类名直接访问静态的方法。静态变量是无法在外部类以外的类用<类名.>出来的。
  3. 匿名内部类
    匿名类需要借助接口类来实现。
    匿名类没有构造方法,与类名相同的方法被认为是普通方法处理。
  4. 方法内部类
    可以直接访问外部类的属性和方法。

外部类被加载时,所有内部类都不被加载,内部类被调用时被加载,匿名内部类不清楚何时加载。除静态内部类以外的内部类是不允许含有静态方法,静态成员变量(成员内部类允许有static final 成员变量,但不允许只有static修饰的成员变量)或静态块的。

就只总结了这些,望大牛们在补充或指正错误。