美文网首页
Java内部类与外部类的那些事

Java内部类与外部类的那些事

作者: stringwu | 来源:发表于2020-03-28 20:09 被阅读0次

Java中的内部类又分为非静态内部类(匿名内部类也是非静态的内部类)和静态内部类,两者与外部类的关系是不一样的,创建的方式也不一样。

1 非静态内部类

Java的非静态内部类在构造的时候,会将外部类的引用传递进来,并且作为内部类的一个属性,因此,内部类会隐式地持有其外部类的引用。也就是非静态内部类在构造的时候需要有一个外部类的实例传递进来进行构造,不能像普通的Java类那样直接就可以通过 new来生成;一个简单的例子如下:

 1 import java.util.ArrayList;
 2 import java.util.LinkedList;
 3 import java.util.List;
 4 import java.util.Queue;
 5 import java.util.Scanner;
 6 
 7 public class Main {
 8 
 9     /**
10      * @param args
11      */
12     public  int k=3;
13     private static String string="Java";
14     protected float j=1.5f;
15     public static void show(){
16         System.out.println("show");
17     }
18     private void add(){
19         System.out.println("add");
20     }
21     public static void main(String[] args) {
22         // TODO Auto-generated method stub
23         Main m=new Main();
24         //合法的非静态内部类的构造方式
25         Child c=m.new Child();
26         //Child c=new Child() 这是不合法的构造方式
27         c.test();
28  
29     }
30 //内部类Child
31   class Child{
32      public int i;
33      public void test(){
34          System.out.println("k=:"+k);
35          System.out.println("string:"+string);
36          add();
37          System.out.println("j=:"+j);
38          show();
39      }
40      
41  }
42 
43 }

并且非静态的内部类可以访问外部类的所有成员变量与方法,包括静态的成员变量与方法,执行内部类Child的test()方法就可以得到下面的结果:

1 k=:3
2 string:Java
3 add
4 j=:1.5
5 show

2 静态内部类

Java中的静态内部类在构造的时候并不需要外部类的引用,因此静态的内部类不会持有外部类的引用,并且静态内部类只能访问外部类的静态成员变量和方法。一个简单的例子为(上面的代码做一些简单的改动):

 1 public class Main {
 2 
 3     /**
 4      * @param args
 5      */
 6     public  int k=3;
 7     private static String string="Java";
 8     protected float j=1.5f;
 9     public static void show(){
10         System.out.println("show");
11     }
12     private void add(){
13         System.out.println("add");
14     }
15     public static void main(String[] args) {
16         // TODO Auto-generated method stub
17         Main m=new Main();
18         //Child c=m.new Childe();//非法
19         Child c=new Child();
20         c.test();
21  
22     }
23   static class Child{
24      public int i;
25     
26      public void test(){
27 //         System.out.println("k=:"+k);//不能访问外部类非静态变量
28          System.out.println("string:"+string);
29          //add(); //不能访问外部类的非静态方法
30 //         System.out.println("j=:"+j);
31          show();
32      }
33      
34  }
35 
36 }

从上面的代码可以看到,静态内部类的创建方式与普通的Java类的创建方式一样,执行第21行代码就可以得到如下结果:

 string:Java
show

3 杂谈

Java的非静态内部类的这种创建方式,会隐式地持有外部类的引用,而且默认情况下这个引用是强引用,因此,如果内部类的生命周期长于外部类的生命周期,程序很容易就产生内存泄漏(你认为垃圾回收器会回收掉外部类的实例,但由于内部类持有外部类的引用,导致垃圾回收器不能正常工作)。为了避免这种情况的发生,你可以在内部类的内部显示持有一个外部类的软引用(或弱引用),并通过构造方法的方式传递进来,在内部类的使用过程中,先判断一下外部类是否被回收;

关于内存泄漏的这一点,有参考技术小黑屋的两篇文章:Android中Handler引起的内存泄露避免Android中Context引起的内存泄露

相关文章

  • (java知识小总结二)2018-05-31

    5.2Java 中的静态内部类:静态内部类是 static 修饰的内部类 特点:(1)、 静态内部类不能直接访问外...

  • java se 成员内部类

    一个类内部包含另一个类身体与心脏分类:1、成员内部类2、局部内部类(匿名内部类) 1、成员内部类 注:内用外可直接...

  • kotlin之内部类,匿名内部类与伴生对象

    个人博客:haichenyi.com。感谢关注 内部类   kotlin的内部类与java的内部类有点不同java...

  • Java 中的方法内部类

    Java 中的方法内部类 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内...

  • Java内部类与外部类的那些事

    Java中的内部类又分为非静态内部类(匿名内部类也是非静态的内部类)和静态内部类,两者与外部类的关系是不一样的,创...

  • scala中的内部类

    scala的内部类与java的内部类有些不同,Java中的内部类是包含了它的类的成员,Scala中,内部类的作用域...

  • Java内部类

    Java内部类 大纲: java内部类有什么特点?为什么需要内部类? 非静态内部类持有外部类的引用 内部类的分类。...

  • PHP转JAVA的记录

    Java 数组 内部类 内部类的创建:内部类可以对包内其他类隐藏想实现一个接口时, 不想新建类文件 内部类可以访问...

  • 内部类

    内部类可以分为:非静态内部类;静态内部类;匿名内部类。 一、内部类 首先要说,Java为什么要使用内部类?java...

  • 面试官:谈谈你对Java内部类的理解?

    java中的内部类可以分为普通内部类(成员内部类),静态内部类,局部内部类和匿名内部类。 成员内部类 成员内部类就...

网友评论

      本文标题:Java内部类与外部类的那些事

      本文链接:https://www.haomeiwen.com/subject/aegsuhtx.html