java依赖关系内部类_Java基础8:深入理解内部类

Java基础8:深入理解内部类

内部类初探

一、什么是内部类?

内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问权限)。内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类

二、内部类的共性

(1)内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。

(2)内部类不能用普通的方式访问。

(3)内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量 。

(4)外部类不能直接访问内部类的的成员,但可以通过内部类对象来访问

内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。

因为当某个外围类的对象创建内部类的对象时,此内部类会捕获一个隐式引用,它引用了实例化该内部对象的外围类对象。通过这个指针,可以访问外围类对象的全部状态。

通过反编译内部类的字节码,分析之后主要是通过以下几步做到的:

1 编译器自动为内部类添加一个成员变量, 这个成员变量的类型和外部类的类型相同, 这个成员变量就是指向外部类对象的引用;

2 编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为1中添加的成员变量赋值;

3 在调用内部类的构造函数初始化内部类对象时, 会默认传入外部类的引用。

二、使用内部类的好处:

静态内部类的作用:

1 只是为了降低包的深度,方便类的使用,静态内部类适用于包含类当中,但又不依赖与外在的类。

2 由于Java规定静态内部类不能用使用外在类的非静态属性和方法,所以只是为了方便管理类结构而定义。于是我们在创建静态内部类的时候,不需要外部类对象的引用。

非静态内部类的作用:

1 内部类继承自某个类或实现某个接口,内部类的代码操作创建其他外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。

2 使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响

3 如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了”多重继承”。

三、那静态内部类与普通内部类有什么区别呢?问得好,区别如下:

(1)静态内部类不持有外部类的引用在普通内部类中,我们可以直接访问外部类的属性、方法,即使是private类型也可以访问,这是因为内部类持有一个外部类的引用,可以自由访问。而静态内部类,则只可以访问外部类的静态方法和静态属性(如果是private权限也能访问,这是由其代码位置所决定的),其他则不能访问。

(2)静态内部类不依赖外部类普通内部类与外部类之间是相互依赖的关系,内部类实例不能脱离外部类实例,也就是说它们会同生同死,一起声明,一起被垃圾回收器回收。而静态内部类是可以独立存在的,即使外部类消亡了,静态内部类还是可以存在的。

(3)普通内部类不能声明static的方法和变量普通内部类不能声明static的方法和变量,注意这里说的是变量,常量(也就是final static修饰的属性)还是可以的,而静态内部类形似外部类,没有任何限制。

==为什么普通内部类不能有静态变量呢?==

1 成员内部类 之所以叫做成员 就是说他是类实例的一部分而不是类的一部分

2 结构上来说 他和你声明的成员变量是一样的地位一个特殊的成员变量 而静态的变量是类的一部分和实例无关

3 你若声明一个成员内部类 让他成为主类的实例一部分 然后又想在内部类声明和实例无关的静态的东西 你让JVM情何以堪啊

4 若想在内部类内声明静态字段 就必须将其内部类本身声明为静态

非静态内部类有一个很大的优点:可以自由使用外部类的所有变量和方法

下面的例子大概地介绍了

1 非静态内部类和静态内部类的区别。

2 不同访问权限的内部类的使用。

3 外部类和它的内部类之间的关系

//本节讨论内部类以及不同访问权限的控制

//内部类只有在使用时才会被加载。

//外部类B

public class B{

int i = 1;

int j = 1;

static int s = 1;

static int ss = 1;

A a;

AA aa;

AAA aaa;

//内部类A

public class A {

//       static void go () {

//

//       }

//       static {

//

//       }

//     static int b = 1;//非静态内部类不能有静态成员变量和静态代码块和静态方法,

// 因为内部类在外部类加载时并不会被加载和初始化。

//所以不会进行静态代码的调用

int i = 2;//外部类无法读取内部类的成员,而内部类可以直接访问外部类成员

public void test() {

System.out.println(j);

j = 2;

System.out.println(j);

System.out.println(s);//可以访问类的静态成员变量

}

public void test2() {

AA aa = new AA();

AAA aaa = new AAA();

}

}

//静态内部类S,可以被外部访问

public static class S {

int i = 1;//访问不到非静态变量。

static int s = 0;//可以有静态变量

public static void main(String[] args) {

System.out.println(s);

}

@Test

public void test () {

//           System.out.println(j);//报错,静态内部类不能读取外部类的非静态变量

System.out.println(s);

System.out.println(ss);

s = 2;

ss = 2;

System.out.println(s);

System.out.println(ss);

}

}

//内部类AA,其实这里加protected相当于default

//因为外部类要调用内部类只能通过B。并且无法直接继承AA,所以必须在同包

//的类中才能调用到(这里不考虑静态内部类),那么就和default一样了。

protected class AA{

int i = 2;//内部类之间不共享变量

public void test (){

A a = new A();

AAA aaa = new AAA();

//内部类之间可以互相访问。

}

}

//包外部依然无法访问,因为包没有继承关系,所以找不到这个类

protected static class SS{

int i = 2;//内部类之间不共享变量

public void

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值