zoukankan      html  css  js  c++  java
  • 【JAVA】java内部类分析详解

    内部类:

           正常的类是定义在一个.java文本文件的最外层的,也就是,定义一个类,这个类外面没有任何包含{}作用域的元素了,但是内部类是定义在某个类内部的类。

           为什么java要提供这样的类定义方式呢?因为如果向往常一样定义一个类,那么要么是public class Cls ,要么是 class Cls,想要用这些类,直接引用即可,但是当编程时如果需要需要定义一个类,却只想让某一个类用到这个类,不希望这个类被其他人使用,就用到内部类了。

     

    Java中的内部类分四种

    1.       非静态内部类

    a)         成员内部类 member inner class

    b)        局部内部类 local inner class

    c)         匿名内部类 anonymous inner class

    2.       静态内部类 static inner class (嵌套类 nested class

     

     

    非静态内部类

           非静态内部类就是没有static关键字修饰的类

           需要让内部类和他的外部类之间有交互时使用

     

     

    成员内部类:

           内部类定义的位置在类中的成员位置,也就是说在类中的最外层的{}里面

           成员内部类可以保证让内部类访问外部类的所有成员包括私有的,包括静态的

           外部类之外访问: 外部类.内部类

           外部类之外new:要用一个已存在的内部类对象new p.new Inner()

           内部类访问他的外部类成员:外部类.this.成员

     

      为什么成员内部类可以和外部类之间互相交互呢?

        因为成员在定义内部类后,编译时编译器自动在内部类中加入一个隐式字段,这个字段是个指向他的外部类对象的引用,在内部类的构造函数中对其进行初始化,

        所以,内部类对象持有一个外部类对象的引用,那么二者就能互相访问。

     

    局部内部类:

           定义在某个成员方法中,类似于局部变量的类

           用法与局部变量相同,不能用public等修饰

           能访问在该方法的其他位置定义的final变量,非final不可

           能访问该方法所在类的成员

           只能在该方法的作用域中使用,也就是外部类不能使用,外部类之外更不能使用

     

      为什么局部内部类只能访问final局部变量(或者相当于final的)呢?

        当局部内部类对该内部类所在的方法的某个局部变量进行访问时,相当于在内部类里面定义一个成员,然后把局部变量的值赋值给他。

        所以 一旦修改这个变量,会让编译器认为这个是过期的,那么就不知道该给内部类成员变量哪个值。

        所以在内部类中只能使用final外部变量保证这个值不被修改

        如果外面的函数中某个值在内部类中用到了,那么这个值不可以继续被修改

        1.内部类使用非final

          

          分析 函数中的变量 i 并没有被改变,所以这是(相当于final)的变量。可以成功编译

     

        2.内部类修改非final

          

          编译错误

          分析:不能在内部类中修改外部函数中的局部变量。

     

        3.内部类使用非final 在函数中修改

          

          编译错误:

          分析:内部类一旦使用了某个外部函数的变量,就相当于编译器给这个变量自动加了final,所以变量不能被修改了。

        4.在函数中修改内部类没有使用过的非final

          

          编译成功。

          变量j没有在内部类中使用,所以不会出错

        5.在内部类使用外部函数的final变量

          由于final的特性 可以得知,final保证了变量不能被修改,所以无论在哪要改变这个都会出错,只能在内部类中使用

     

      总结:

        对于外部函数中的某个局部变量,只要在内部类中出现了,可以看做编译器立马给这个变量加上了final,保证他不会被修改。

        对于内部类中没有出现的局部变量,那么与final无关

    静态内部类:

      静态内部类就是嵌套类

      内部类中只能访问外部类的静态成员(这点与成员内部类不同),因为static在静态存储区

      在外部类之外声明用 外部类.内部类 

      在类外new  直接 new 外部类.内部类即可,因为不存在对象。

        

    匿名内部类:

      不包含名字的内部类

      在定义时就产生一个对象并且只使用这一次

      常常用于在给一个函数传入某个参数时使用

      定义一个匿名内部类,必须是在一直某个父类或者接口的情况下定义。

      定义格式是  new 父类或接口() {  成员  };

      匿名内部类因为是匿名的,所以没有构造方法,想要实现构造方法的功能要用构造代码块 {}

      匿名内部类只能访问final局部变量,因为它实际上是一个局部内部类的变种

      匿名内部类创建时隐式调用了父类的构造方法,如果父类的构造有参数,那么必须在()括号中传入(x) 此时不需要final  

     

     

     

     

    注:

      下划线代表仍存在疑问。  

     

  • 相关阅读:
    116. Populating Next Right Pointers in Each Node
    117. Populating Next Right Pointers in Each Node II
    经典排序算法总结(含JAVA代码实现)
    Android面试算法篇(java)
    Android单例模式
    Android进阶-Android APK安装过程
    Android进阶-Android性能优化总结
    Android进阶-Android内存泄漏总结
    Android进阶-Android权限处理
    Android进阶-一个APP从启动到主页显示经过了哪些过程?
  • 原文地址:https://www.cnblogs.com/heanqing/p/4907664.html
Copyright © 2011-2022 走看看