zoukankan      html  css  js  c++  java
  • Java内部类总结

    内部类是一种编译器现象,与虚拟机无关。编译器将会把内部类翻译成用美元符号$分隔外部类名与内部类名的常规类文件,而虚拟机对此一无所知。编译器为了引用外部类,生成了一个附加的实例域this$0

    为什么要用内部类?

    • 内部类可以访问所在类域中的数据(包括私有);
    • 内部类可以在同一包中被隐藏;
    • 匿名内部类在实现回调时非常方便;

    特殊语法

    • OuterClass.this表示外部类对象引用,比如Employee.this.id;
    • OuterObject.new InnerClass()显式调用内部对象的构造函数,例如this.new Payroll(10000);
    • OuterClass.InnerClass其它类访问内部类;
    • OuterClass$InnerClass编译器翻译成JVM能够识别的类,内部类对JVM是透明的.

    内部类表现形式

    • 简单内部类
    • 局部的内部类
    • 匿名内部类
    • 静态内部类

    简单内部类

    每个内部类对象都有一个指向外部对象的隐式引用outer;每次外部类对象初始化一个内部类对象时都会把自己的this引用传给内部类对象的隐式的构造函数,以下是模拟的过程:

    public class Outer{
        //隐式会把this传给内部类对象的构造函数,实际这个过程看不到也不用去写.
        public void function(){
            Inner inner = new Inner(this);
            ....
        }
    
        public class Inner{
        //内部类有个隐式的构造函数生成外部类对象的引用,实际这个过程看不到也不用去显示调用
            private Outer outer;
            public Inner(Outer outer){
                this.outer = outer;
            }
        }
    }

    实例如下

    public class Employee {
    
        // 实例化对象时,在调用构造函数之前前初始化字段;
        private int id; // 实例化对象时初始化为0
        private String name; // 实例化对象时初始化为null
        public Employee(int id, String name) {
            this.id = id;
            this.name = name;
    
        }
    
        public void start(){
            //局部的内部类
            class Computer{
                private int seq;
                public Computer(int seq){
                    this.seq = seq;
    
            public void run(){
                    System.out.println(seq + " computer is run");
                }
            }
    
            Computer c = new Computer(2015);    
            c.run();
        }
    
        //简单内部类
        public class Payroll {
            private int pay;
            //以下是模拟生成外部类对象的引用
            // private Employee outer;
            // public Payroll(Employee e) {
            // this.outer = e;
            // }
    
            public Payroll(int pay) {
                this.pay = pay;
            }
    
            // 每个内部类对象都有一个指向外部对象的隐式引用outer,可以把id和name想象成outer.id和outer.name
            public void printPay() {
                //if (id == 1) {
                    if(Employee.this.id ==1){
                    System.out.println("name is " + name);
                    System.out.println("pay is: " + pay);
                    System.out.println("----------------------------");
                } else {
                    System.out.println("you can not print pay");
                }
            }
        }
    
        public void printPayroll() {
            //Payroll p = new Payroll(10000);
            Payroll p = this.new Payroll(10000);
            p.printPay();
        }
    
        public static void main(String[] args) {
            Employee e1 = new Employee(1, "a");
            Employee e2 = new Employee(2, "b");
            e1.printPayroll();
            e2.printPayroll();
            e1.start();
        }
    }

    局部的内部类

    在外部类方法中定义的内部类称为局部内部类,局部内部类不能用修饰符(public or private)定义.只能访问局部方法作用域的final变量.

        public void start(){
            final int num = 2015;
            class Computer{
                private int seq;
                public Computer(int seq){
                    this.seq = seq;
                }   
    
                public void run(){
                    System.out.println("seq is: " + seq + ", num is: " + num);
                }
            }   
    
            Computer c = new Computer(2015);
            c.run();
        }

    匿名内部类

    语法如下,SuperType可是接口也可以是类.匿名内部类不能有构造函数.匿名内部类隐式地继承了一个父类或者实现了一个接口。

    new SuperType(construction parameters)
    {

    inner class method and data
    

    }

    或者是
    new InterfaceType()
    {

    inner class method and data
    

    }

    实例

    new Thread() {
                //匿名内部类
                @Override
                public void run() {
                    System.out.println("----------------------------");
                    System.out.println("this is a anonymous class run");
                }
    }.start();

    静态内部类

    静态内部类与其它内部类相似,不同之处在于静态内部类没有指向外部类的引用.当不需要访问外部对象时,可以考虑使用静态内部类.被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。 注意,声明在接口中的内部类自动成为public和static。
    实例

    public class StaticInner {
        private static int a = 4;
    
        // 静态内部类
        public static class Inner {
            public void test() {
                // 静态内部类可以访问外部类的静态成员
                // 并且它只能访问静态的
                System.out.println(a);
            }
        }
    
        public static void main(String[] args) {
            StaticInner.Inner inner = new StaticInner.Inner();
            inner.test();
        }
    }
  • 相关阅读:
    <QT学习>串口QSerialPort类同步与异步接收和发送数据
    <QT学习>QT生成与调用共享库
    《Pinctrl和GPIO子系统的使用》
    《查询方式的按键驱动程序》
    《C库 — sprintf字符串格式化命令,把格式化的数据写入某个字符串中》
    《C库 — 字符串合并函数strcat 字符串常量导致程序崩溃》
    Ex 5_22 在此我们基于以下性质给出一个新的最小生成树算法..._第九次作业
    Ex 5_21 无向图G=(V,E)的反馈边集..._第九次作业
    Ex 5_33 实现一个关于公式长度(其中所有文字总的出现次数)为线性时间的Horn公式可满足性问题_第十次作业
    Ex 5_28 Alice想要举办一个舞会..._第十次作业
  • 原文地址:https://www.cnblogs.com/csu_xajy/p/4304443.html
Copyright © 2011-2022 走看看