java 原生解析内部类_深入解析Java中的内部类

概述

最近学习python,发现python是支持多继承的,这让我想起java是通过内部类实现的这套机制。这篇文章不是讲如何通过内部类实现多继承,而是总结一下内部类的类型和使用方法。

java内部类分为:

非静态内部类

静态内部类

局部内部类

匿名内部类

内部类在android源码中被大量的使用,先介绍一下这四种内部类的共同点:

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

内部类不能用普通的方式访问。内部类是外部类的一个成员,因为内部类可以自由的访问外部类的成员,包括private成员。

内部类声明为静态的,就不能随意的访问外部类的成员变量了,此时内部类只能访问到外部类的静态成员变量。

接下来,分别介绍一下这几种内部类。

非静态内部类

当一个类作为另一个类的非静态成员时,则这个类就是一个非静态内部类。

创建非静态内部类的示例代码如下:

class outclass {

class innerclass {}

}

当我们用javac去编译的时候,发现生成了两个.class文件:outclass.class和outclass$innerclass.class。如下图所示:

295c148b26dbb7f969ea92620f4d4174.png

从外部类的非静态方法中实例化内部类

在外部类中访问内部类是很容易的,直接创建内部类对象,然后通过对象实例调用类内的方法即可。示例代码如下:

public class outclass {

private static int a = 0;

public void makeinner() {

innerclass inclass = new innerclass();

inclass.seeouter();

}

public static void main(string[] args) {

outclass oclass = new outclass();

oclass.makeinner();

}

class innerclass {

public void seeouter() {

system.out.println(a);

a++;

}

}

}

运行结果如下:

0

从外部类的静态方法中实例化内部类

在外部类中访问内部类是比较简单的,可以直接new出内部类对象,但是如果想在外部类的外部使用内部类,接不能直接new内部类名的方式了,而是需要如下方式:

outclass.innerclass innerclass = new outclass().new innerclass();

也就是说,在外部调用非静态内部类,需要先实例化外部类,然后通过外部类对象再去实例化内部类。示例代码如下:

public class outclass {

private static int a = 0;

public void makeinner() {

innerclass inclass = new innerclass();

inclass.seeouter();

}

public static void main(string[] args) {

outclass oclass = new outclass();

oclass.makeinner();

outclass.innerclass innerclass = new outclass().new innerclass();

innerclass.seeouter();

}

class innerclass {

public void seeouter() {

system.out.println(a);

a++;

}

}

}

运行结果:

0

1

内部类的this引用

普通的类可以使用this引用当前的对象,内部类也是如此。但是假若内部类想引用外部类当前的对象呢?可以使用如下方式:

外部类名.this

示例代码如下:

public class outclass {

private static int a = 0;

public void makeinner() {

innerclass inclass = new innerclass();

inclass.seeouter();

}

public static void main(string[] args) {

outclass oclass = new outclass();

oclass.makeinner();

outclass.innerclass innerclass = new outclass().new innerclass();

innerclass.seeouter();

}

class innerclass {

public void seeouter() {

system.out.println(this);

system.out.println(outclass.this);

}

}

}

静态内部类

上面介绍了非静态内部类,接下来我们学习神马是静态内部类。

静态内部类就是在外部类中扮演一个静态成员的角色,创建静态内部类和创建非静态内部类的形式很相似,只是class前面多了一个static修饰符。

注意,外部类是不可能使用static修饰符进行修饰的。

示例代码如下:

class outclass {

static class innerclass {

}

}

用javac命令编译一下,可以看到一样都是有两个.class文件,如下图所示:

926d9c088985c4001f29fb2aa12d1850.png

从外部类的非静态方法中实例化静态内部类

从外部类中访问静态内部类,和在外部类中访问非静态内部类是一样的。但是,需要注意一点,此时静态内部类只能访问外部类的静态成员,无法访问非静态成员了。

示例代码如下:

public class outclass {

private static int a = 0;

private int b = 1;

public void makeinner() {

innerclass inclass = new innerclass();

inclass.seeouter();

}

public static void main(string[] args) {

outclass oclass = new outclass();

oclass.makeinner();

}

static class innerclass {

public void seeouter() {

system.out.println(this);

system.out.println(a);

// system.out.println(b);

}

}

}

执行结果如下:

outclass$innerclass@79a340

0

从外部类静态方法中实例化静态内部类

注意:

因为静态内部类是外部类的静态成员,而静态成员是跟类绑定,而不是跟类实例化的对象绑定。所以,在外部类的静态方法中实例化内部类,是不需要先实例化外部类的。

示例代码如下:

public class outclass {

private static int a = 0;

private int b = 1;

public void makeinner() {

innerclass inclass = new innerclass();

inclass.seeouter();

}

public static void main(string[] args) {

outclass oclass = new outclass();

oclass.makeinner();

outclass.innerclass inclass = new outclass.innerclass();

inclass.seeouter();

}

static class innerclass {

public void seeouter() {

system.out.println(this);

system.out.println(a);

// system.out.println(b);

}

}

}

匿名内部类

匿名内部类在android应用开发中简直是泛滥,各种listener对象的实现很多都是通过匿名内部类。

匿名内部类从名字上就可以知道这是代表没有类名的内部类,通常用来简化代码。

相信写java的同学都使用过线程,那thread的时候我们可以传一个runnable对象,也可以传一个匿名内部类。示例代码如下:

public class outclass {

public void testanonymousclass() {

thread t = new thread(new runnable() {

@override

public void run() {

for (int i = 0; i < 10; i ++) {

system.out.println(i);

try {

thread.sleep(500);

} catch (interruptedexception e) {

e.printstacktrace();

}

}

}

});

t.start();

system.out.println("another thread is running...");

}

public static void main(string[] args) {

outclass oclass = new outclass();

oclass.testanonymousclass();

}

}

执行结果如下:

another thread is running...

希望与广大网友互动??

点此进行留言吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值