java内部类学习总结

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修饰的成员变量)或静态块的。

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

猜你喜欢

转载自blog.csdn.net/bacoder/article/details/73338583