内部类:

在Java中的类一共分为以下几种:

①普通类:就是大家平时声明的类,定义时用public修饰和不用public修饰的类,用public修饰的在Java中只能有一个并且类名要和文件名相同。不用public修饰的类只能在同包中被调用,因为没有导入的包。

②抽象类:具有承载抽象方法能力的类,是对类的抽象。

③匿名类:抽象类在实例化对象的时候调用构造方法,会生成匿名类,匿名类要实现抽象类的所有抽像方法,所以抽象类即使有构造方法也不能实例化对象。

④外部类:内部类的外部类体,是用来承载内部类的载体。

⑤内部类:现在要来讨论我们今天的重点了,内部类。

在Java中内部类中可以有属性、方法、构造方法。在外部类中,可以调用内部类中的属性和方法(包括私有属性和私有方法),同时内部类也可以调用外部类中的属性和方法(包括私有属性和私有方法),内部类和外部类的关系其实是所属关系。其实把内部类看成是外部类的一个方法可能更好理解一些,在类中嘛,所以可以访问外部类的属性和方法,同时又属于外部类,则外部类又可以调用它的属性跟方法,这里要注意一个点,外部类调用内部类的属性和方法时要创建内部类的对象,而内部类调用外部类时直接调用即可

例:

public class Test {
    private int a = 1;
    private int b = 2;
    public class InTest{
        private int c = 3;
        private int d = 4;
        public int add(){
            return a + b;   //调用外部类的私有属性,直接调用
        }
        private void printf(){
            System.out.println("我是内部类的方法");
        }
    }

    public void printf(){    //调用内部类的私有方法
        InTest inTest = new InTest(); //调用内部类的方法时,要创建内部类的对象
        inTest.printf();
        inTest.add();
    }
    
    public int add(InTest inTest){
        c + d;   //外部类直接调用内部类的属性会报错
        return inTest.c + inTest.d;
        
    }
}

那么内部类在内存中的存储方式是怎样的呢,首先来讨论一下类是怎样加载的,所有的类模板其实都是Class的对象,在Java中jvm将类从外存中加载到内存时,将程序拆分成一个byte数组,此时在栈中创建一个Class类的对象名,同时在堆中开辟了一片内存空间,创建了一个 .class的对象。

public class Test {
    int b;
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        Class test = Test.class;
        Test test1 = (Test) test.newInstance();  //创建Test的对象
        Test test2 = new Test();     //直接创建一个Test的对象
        System.out.println(test1.b);  
        System.out.println(test2.b);
    }
}

java 内部类中使用enum java内部类可以用public修饰吗_外部类

类加载器先创建了一个Class的对象test,及为Test.class,然后调用test的newInstance()方法,创建了test1这个对象。test2是传统的创建对象的方式。

现在来看一下内部类的在内存中的存储方式:我们看到想要创建类,首先在堆中你要创建一个类模板,然后才能创建对象,内部类也是一个类嘛,他的类模板在外部类的对象里,所以要想创建内部类的对象,首先你要先有内部类的类模板吧,此时你就要创建一个外部类的对象才能有内部类的模板。如图所示:

public class TestIn {
    public static void main(String[] args) {
        Test.InTest t2 = new Test().new InTest();
        t2.printf();
    }

}

java 内部类中使用enum java内部类可以用public修饰吗_java 内部类中使用enum_02

如图所示,先创建了一个外部类的对象,拿到InTest.class模板,然后才能创建内部类的对象,这样也可以解释了为什么创建内部类对象时要先创建外部类的对象。其实结合内存我们可以发现很多东西,比如静态的内部类,这里就不画图了,用代码实现一下就好了,其实和静态方法一样,外部类加载时就内部类加载到了元数据区,所以不用创建内部类模板了。如果不太懂可以参考我之前的博客,static和final的用法。下面是代码的实现:

public class TestIn {
    public static void main(String[] args) {
        Test.InTest t2 = new Test.InTest();
        t2.printf();
    }

}

今天就分享到这吧........