一直对java内部类不大熟悉,代码中也很少用,有说法是,有很多公司觉得使用内部类会造成代码不够简明的问题,所以规范上禁止或要求少用内部类,个人看了内部类的一些知识后,觉得这个说法有它的实际道理,大部分正常非必需的情况下,确实不使用这玩意比较好,但是内部类又是java的一个重要模块内容,尤其是JDK中很多底层的类都用到内部类,所以还是需要去了解的,以免看源码时被卡住,但是实际开发应用中不是非常必要(就是只有这样搞才能实现目标功能)就别用了。
内部类在java中分成几种:
最常见的一种是:成员内部类
顾名思义就是它在外部类的地位相当于一个成员对象或成员方法,什么意思?从访问权限来看,它和其它成员方法一样,能访问外部类所有的成员数据和方法,包括private域,跟其他成员方法一样。另外跟外部类的非静态成员数据一样,需要先创建外部类的对象后才能创建内部类对象,这也容易理解,成员内部类就是外部对象的一个非静态成员,没有外部类的对象就不能使用这个成员,它是外部类对象的一部分。简单的例子如下
public class InnerClassTest
{
privateString data;
privatevoid fun1(){
System.out.println("InnerClassTest.fun1");
}
publicstatic void main(String[] args) {
InnerClassTestout = new InnerClassTest();
InnerClassTest.innerin=out.new inner ();
in.innerfun();
}
publicclass inner{
publicvoid innerfun()
{
InnerClassTest.this.fun1();
}
}
}
需要注意的是成员内部类不能含有static变量或者方法。还有内部成员类的初始化形式也比较特殊,需要先new外部类对象,再用外部类对象.new inner()的形式创建内部类,确实跟熟悉的创建对象的语句不一样。
另外一种内部类是:局部内部类
顾名思义,它是在方法域中的内部类,跟方法域中的局部变量有相似之处,第一,它的生命周期和局部变量一样,只在局部域中存活。第二它的访问权限范围和局部变量一样,只能范围当前作用域和外层域的数据,不能访问其他域的数据。见例子
public class InnerClassTest
{
privateString data;
privatevoid fun(String c1){
classinner{
Strings1;
publicinner()
{
s1=c1;
}
}
innerin=new inner();
System.out.println(in.s1);
}
publicstatic void main(String[] args) {
InnerClassTestout = new InnerClassTest();
out.fun("hello");
}
}
局部内部类需要注意的地方比较少,就记住它的生命周期和访问范围和局部变量是一样的。
总而言之,成员内部类和局部内部类的理解可以类比类的成员和方法中的局部变量来理解,也就容易记住了。只是成员内部类创建内部类的形式需要注意下。
接下来是:内部嵌套类
所谓的内部嵌套类,可以理解成静态成员内部类,它和上面所说的成员内部类的区别就是它是用static修饰的,也就是说它是不需要依赖于外部类的对象,而是直接属于外部类,可以通过外部类.inner的形式访问,例子:
public class InnerClassTest
{
privateString data;
staticprivate void fun(String c1){
}
publicstatic void main(String[] args) {
InnerClassTest.inner.innerfun();
}
publicstatic class inner{
staticString s1;
staticpublic void innerfun()
{
InnerClassTest.fun("hello");
System.out.println("hello");
}
}
}
如上面例子一样,内部嵌套类和静态成员方法一样,允许静态方法存在,访问的形式也类似外部类的静态成员,另外跟静态成员方法一样,内部嵌套类里面只能调用外部类的静态成员变量和静态成员方法,而不能调用非静态成员。
最后是一个比较广泛在安卓开发或者多线程中使用的:匿名内部类
顾名思义,匿名内部类就是没有直接命名的内部类,可以和java中常见的匿名对象联系记忆。例子:
public class InnerClassTest
{
publicinterface inner{
}
publicstatic void main(String[] args) {
newinner(){
Strings1;
publicvoid innerfun()
{
System.out.println("hello");
}
}.innerfun();
}
}
需要注意的是,虽然匿名内部类可以在创建对象的时候才实现具体的成员变量和成员方法,但是必须先定义个框架,其实有点像声明,而且是定义成接口才行,一般这种匿名内部类在安卓,多线程,消息回调中使用比较多,实际上是实现了某种接口的内部类,只是没有明显的名字和implements。
总而言之,内部类的分析就这四大类,为了方便记忆,可以跟外部类的非静态成员,方法中的局部变量,外部类的静态成员,匿名对象这四个事物关联记忆。因为它们的生命周期,访问权限和使用形式都有相似之处。内部类需要了解,这样我们对一些使用到内部类的代码能看得懂,尤其是JDK内部的很多源码有读析能力,但是真心不建议在实际中过多使用,除非非用不可,毕竟代码越简洁越容易后期的修改和维护以及bug的排查。