• Java 内部类使用


    1.  内部类结束

      内部类具有封装型,隐藏程序细节。主要有非静态内部类,静态内部类,匿名内部类几种。

    2. 非静态内部类

      可用把内部类当作外部类的成员变量/方法来使用,需要依赖外部类对象来使用

    public class OutClass {
        private String outStr;
    
        public void display(){
            System.out.println(outStr);
        }
    
        //内部类
        public class InnerClass{
            private String innerStr;
    
            public InnerClass() {
                innerStr = "innner class";
            }
    
            public void display(){
                System.out.println("Inner class");
                System.out.println(innerStr);
            }
        }
    
        public static void main(String[] args) {
            OutClass outClass = new OutClass();
            outClass.display();
    
            OutClass.InnerClass innerClass = outClass.new InnerClass();  //创建内部类需要外部类对象调用
            innerClass.display();
        }
    }

      非静态内部类还可以定义在方法内

    public class OutClass02 {
        private String outStr;
    
        public void display(){
            class InnerClass{
                private String innerStr;
    
                public InnerClass() {
                    innerStr = "innner class";
                }
    
                public void display(){
                    System.out.println("Inner class");
                    System.out.println(innerStr);
                }
            }
            InnerClass innerClass = new InnerClass();  //可以直接创建内部类
            innerClass.display();
        }
    
        public static void main(String[] args) {
            OutClass02 outClass02 = new OutClass02();
            outClass02.display();
        }
    }

    2. 静态内部类

      静态内部类使用不需要依赖外部对象

    public class OutClass03 {
        private String outStr;
    
        public void display(){
            System.out.println(outStr);
        }
    
        public static class InnerClass03{
            private String innerStr;
    
            public InnerClass03() {
                innerStr = "innner class";
            }
    
            public void display03(){
                System.out.println("Inner class");
                System.out.println(innerStr);
            }
        }
    
        public static void main(String[] args) {
            OutClass03 outClass03 = new OutClass03();
            outClass03.display();
    
            InnerClass03 innerClass03 = new InnerClass03();  //创建内部类不需要外部类对象调用
            innerClass03.display03();
    
        }
    }

    3. 匿名内部类

      可用直接实现接口创建对象,还可以直接"new 接口名“,重写接口中方法

    public interface InnerInterface {
        void inner();
    }
    public class InnerInterfaceImpl implements InnerInterface {
        @Override
        public void inner() {
            System.out.println("test");
        }
    }
    public class MyApp {
        public static void main(String[] args) {
            //(1)创建对象
            InnerInterface innerInterface = new InnerInterfaceImpl();
            innerInterface.inner();
    
            //(2)匿名内部类
            InnerInterface innerInterface1 = new InnerInterface() {
                @Override
                public void inner() {
                    System.out.println("test1");
                }
            };
            innerInterface1.inner();
        }
    }

      还可用把接口的实现放在类里面,这样就相当于一个内部类,所以调用就需要依赖外部类对象来调用

    public class MyApp2 {
    
        public class InnerInterfaceImpl implements InnerInterface{
            @Override
            public void inner() {
                System.out.println("test2");
            }
        }
    
        public static void main(String[] args) {
            MyApp2 myApp2 = new MyApp2();
            MyApp2.InnerInterfaceImpl innerInterface = myApp2.new InnerInterfaceImpl();
            innerInterface.inner();
        }
    }

    3. 局部内部类和匿名内部类访问局部变量

      (1)局部内部类访问局部变量

    public class Test01 {
        public static void main(String[] args) {
            new Test01().test(6);
        }
        public void test(int b){
            int a = 10;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(a);
                    System.out.println(b);
                    //    System.out.println(a++); 提示错误,变量被final修饰
                    //    System.out.println(b++);
                }
            }).start();
        }
    }

      (2)匿名内部类访问局部变量

    public class Test03 {
        private int age = 12;
        public static void main(String[] args) {
            new Test03().test(20);
        }
    
        public void test(int x){
            class InnerClass{
                public void InPrint(){
                //    System.out.println(x++); 提示错误,变量被final修饰
                    System.out.println(x);
                    System.out.println(age++);  //可以访问成员变量
                }
            }
            new InnerClass().InPrint();
        }
    }

      总结:

        在Java 1.8后虽然在类中不用直接在变量前使用final修饰,但是也不能修改变量的值,对变量进行++会有编译报错。通过反编译.class文件后,也能看到变量会被final修饰

      所以局部内部类和匿名内部类访问局部变量时会被final修饰

       内部类和外部类是处于同一级别的,内部类不会因为定义在方法中就会随着方法的执行完毕被销毁。

      所以当外部类的方法结束后,局部变量就应该被销毁了,但是内部类可能还会存在,这样内部类就会引用了不存在的变量。此时就需要将局部变量复制一份作为内部类的成员变量,这样局部变量死亡后,内部类依然可以访问它,实际访问的是局部变量的“copy”,相当于延长了局部变量的生命周期。

      将局部变量复制作为内部类的成员变量时,就必须要保证两个变量是一致的,如果在内部类修改了成员变量,方法中也就要改变,所以可以把局部变量设置为final,对它初始化后,就不再改变这个变量了,就可以保证内部类的成员变量和方法的局部变量的一致性了,这实际上也是一种妥协,使得局部变量和内部类的建立的拷贝保持一致。

  • 相关阅读:
    MySQL/MariaDB 版本选择
    Linux查看某个进程的磁盘IO读写情况 pidstat
    Oracle 11gR2 Database UNDO表空间使用率居高不下处理
    Linux十字病毒查杀处理
    MySQL字符集与校对
    点与线、线与线之间的位置关系
    [向量] 点积应用-两个向量夹角
    点与线的距离及垂足点
    unity 4.6.1脚本解析出错,没有激活的勾,方法顺序出错
    Error building Player: Exception: Could not start java
  • 原文地址:https://www.cnblogs.com/homle/p/15700970.html
Copyright © 2020-2023  润新知