您的位置:首页 > 其它

内部类和闭包

2015-10-27 20:02 253 查看

内部类和闭包

今天在某java群中看到了这样一个内部类问题,代码如下:

InnerDemo01中有一个内部类Bar,InnerDemo01中的method方法中有一个继承Bar的局部子类InnerClass。InnerClass类中调用了method方法中定义的一个局部变量。

而我们一般都知道,方法中的局部变量会在执行结束后就会被释放,但是内部类访问此变量就形成了闭包。

package com.wrh.innerdemo;

public class InnerDemo01 {
class Bar{
public void show(){
//do ..
}
}
public static void main(String[] args) {
InnerDemo01 innerDemo01=new InnerDemo01();
Bar bar=innerDemo01.method();
bar.show();//你觉得num会输出吗????
}
public Bar  method(){
//String str="wuranghao";
int num=30;
//局部内部类将输出这个局部变量
class innerClass extends Bar{

public void show(){
System.out.println(num);
}
}
return new innerClass();
}

}


运行结果:30

内部类使用外部的局部变量,实际上形成了闭包,也就是捕获了所在方法内的变量,这个被捕获的变量不能随着方法的执行完毕而消失,因为内部类的实例可能还会用到这个变量,所以需要 final 关键字来让这个变量不消失(final 修饰的变量会转为常量,因此不会随着方法的执行完毕而消失)。

如果在内部类中使用到了外部方法的变量,需要使用 final 修饰,否则无法编译通过,但如果使用的是 JDK8,那么即便你不加final 修饰,也是可以编译过的,因为编译器替你加上了。

内部类的一些知识点

1、在创建非静态内部类对象时,一定要先创建其相应的外部类对象。原因是:非静态内部类对象有着指向其外部类对象的引用,可以引用其外部类中的所有public protected private的变量和方法。

2、内部类可以是静态的,即内部类可分为静态内部类和非静态内部类(即普通类)。区别在于静态内部类没有了指向其外部类的引用。

3、非静态内部类中不能有静态属性、静态方法或者又一个静态内部类(内部类的嵌套可以不止一层);但静态内部类可以拥有这一切,即静态属性、静态方法或者静态内部类。

4、局部内部类 即Java的内部类可以是局部的,它可以定义在一个方法甚至一个代码块之内。

5、匿名内部类 Java的匿名内部类的语法规则比较简单,如同匿名数组一样,用于当你只需要创建一个类的对象而并不需要使用它的名字时,这样,匿名内部类的使用能使代码看上去更简洁、更清楚。

6、匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用super关键字调用相应的内容)。如果你想要初始化它的成员变量,有下面几种方法:a) 如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为final;b) 将匿名内部类改造成有名字的局部内部类,这样它就可以拥有构造函数了;c) 在这个匿名内部类中使用初始化代码块。

关于内部类的一些例子讲解可以看这篇博文:http://www.iteye.com/topic/442435
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: