内部类和闭包

内部类和闭包

今天在某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

你可能感兴趣的:(java,内部类,闭包,局部变量,匿名类)