Java学习之内部类

本来写过一次的,后来被我连同反编译后的文件一块删了,就重写了一次

 

内部类除非是外部类的静态内部类,其他的内部类都不能定义静态变量以及静态方法,但是静态常量还是可以定义的。

对于静态内部类来说,他的实例化不依赖于外部类的实例,实例化时没有一个指向外部类实例的参考,因此是无法使用this关键字的,可以使用的只有外部类的静态变量以及静态方法。

 

对于局部内部类以及方法内部类,在内部类中都不能改变外部方法中的变量值。

* 局部类中不能改变外部方法中的变量,虽然可以调用(在JDK8之前,如果要在匿名内部类别中存取局部变量,则该局部变量必须是final,否则会发生编译错误),但本质上是一种程序蜜糖,局部内部类中调用的变量是赋值给了final修饰后局部内部类中的变量——也就是常量。外部方法中的变量声明周期结束,但局部内部类中复制后变量还在。匿名内部类也是如此。

* 参考:https://www.cnblogs.com/dolphin0520/p/3811445.html

    https://openhome.cc/Gossip/Java/AnonymousInnerClass.html

 

Java内部类详解 这篇文章写得确实不错。

 

public class OuterClass {
    static int A = 10;
    int a = 10;

    /*
     * 成员内部类中不能声明静态成员变量以及方法,但可以有静态常量
     * 
     * 成员内部类创建对象时依赖于外部类的实例,成员内部类在实例化时会有一个依赖的外部类的引用(可以用它有一个外部类类型的实例的指针来理解)
     * 
     * 成员内部类在访问外部类中同名的成员是可以用 【外部类.this.成员名用来调用】 变量或方法
     */
    class InnerClass {
//        static int A = 20;// The field A cannot be declared static in a non-static inner type, unless
//                            // initialized with a constant expression
        static final int A = 20;

//        static void staticMethod() {// The method staticMethod cannot be declared static; static methods can only be
//                                    // declared in a static or top level type
//        }

        int a = 20;

        void method() {
            System.out.println("InnerClass.method");
            System.out.println(a);
            System.out.println(OuterClass.this.a);
//            InnerClass.this.method();
        }

    }

    /*
     * 静态内部类中可以声明静态和非静态的成员变量还有方法,但不能使用this关键字,也不能访问外部类中的非静态成员
     * 
     * 静态内部类创建对象时不依赖外部类的实例,外部类的实例未创建就无法调用其非静态的成员
     */
    static class StaticInnerClass {
        static int A = 30;

        static void staticMethod() {
        }

        int a = 30;

        void method() {
            System.out.println("StaticInnerClass.method");
            System.out.println(a);
//            System.out.println(OuterClass.this.a);//No enclosing instance of the type OuterClass is accessible in scope
        }

    }

    void method() {
        int local = 3;
        String str = "str";
        /*
         * 局部内部类中不能声明静态成员变量以及方法,但可以有静态常量
         * 
         * 局部类中不能改变外部方法中的变量,虽然可以调用(在JDK8之前,如果要在匿名内部类别中存取局部变量,则该局部变量必须是final,否则会发生编译错误),
         * 但本质上是一种程序蜜糖,局部内部类中调用的变量是赋值给了final修饰后局部内部类中的变量——也就是常量。
         * 外部方法中的变量声明周期结束,但局部内部类中复制后变量还在。匿名内部类也是如此。
         * 
         * 参考:https://www.cnblogs.com/dolphin0520/p/3811445.html
         * https://openhome.cc/Gossip/Java/AnonymousInnerClass.html
         */
        class InnerClass {

//            static int A = 40;// - The field A cannot be declared static in a non-static inner type, unless
//                                // initialized with a constant expression
            static final int A = 40;

//            static void staticMethod() {// The method staticMethod cannot be declared static; static methods can only be
//                                        // declared in a static or top level type
//            }

            int a = 40;

            void method() {
//                local = 3;//Local variable local defined in an enclosing scope must be final or effectively final
//                str = "";//Local variable str defined in an enclosing scope must be final or effectively final
                System.out.println("InnerClass.method");
                System.out.println(a);
                System.out.println(OuterClass.this.a);
            }
        }
        /*
         * 匿名内部类默认继承类或接口
         * 
         * 匿名内部类中不能声明静态成员变量以及方法,但可以有静态常量
         */
        new OuterClass() {
//            static int A = 50;// - The field A cannot be declared static in a non-static inner type, unless
//                                // initialized with a constant expression
            static final int A = 50;
//            static void staticMethod() {// The method staticMethod cannot be declared static; static methods can only be
//                                        // declared in a static or top level type
//            }

            int a = 50;

            @Override
            void method() {
//                local = 5;//Local variable local defined in an enclosing scope must be final or effectively final
//                str = "";//Local variable str defined in an enclosing scope must be final or effectively final
                System.out.println("OuterClass.method");
                System.out.println(a);
                System.out.println(OuterClass.this.a);
            }
        }.method();
    }

    public static void main(String[] args) {
        new OuterClass().method();
    }
}

 

另外,似乎可以在方法中使用方法内部类中private修饰的成员。

放个自己在做实例串行化时用到的方法内部类的代码,只是一个小的测试

 1     public static void main(String[] args) throws IOException, ClassNotFoundException {
 2 //        往D盘teacher.txt文件中输入两个老师的对象,并在控制台显示出来。
 3         {
 4             class Teacher implements Serializable {
 5                 private static final long serialVersionUID = 1L;
 6                 private String name;
 7 
 8                 public Teacher(String name) {
 9                     super();
10                     this.name = name;
11                 }
12 
13 //                public String getName() {//方法内部类可以直接访问
14 //                    return name;
15 //                }
16 
17                 @Override
18                 public String toString() {
19                     return "Teacher [name=" + name + "]";
20                 }
21 
22                 public void save() throws FileNotFoundException, IOException {
23                     try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(this.name))) {
24                         oos.writeObject(this);
25                     }
26                 }
27 
28                 public /* static */ Teacher load(String name)
29                         throws FileNotFoundException, IOException, ClassNotFoundException {
30                     try (ObjectInputStream osi = new ObjectInputStream(new FileInputStream(name))) {
31                         return (Teacher) osi.readObject();
32                     }
33                 }
34             }
35 
36             Teacher[] teachers = { new Teacher("小楠"), new Teacher("华福") };
37             for (Teacher teacher : teachers) {
38                 teacher.save();
39                 System.out.println(((Teacher) teacher.load(teacher.name)));// 可以使用Teacher类中private封装的成员
40             }
41         }
42     }

 

posted @ 2020-09-24 22:38  康舒服冰红茶  阅读(165)  评论(0编辑  收藏  举报