Java内部类

http://www.cnblogs.com/dolphin0520/p/3811445.html


       顾名思义,内部类就是类的内部的类。从宏观上来观看内部类,可以分为1-静态内部类2-非静态内部类。非静态内部类中又分三种特殊的情况,2.1-成员内部类、2.2-局部内部类、2.3-匿名内部类。


      使用内部类的原因主要有:

      1将逻辑上只会一起使用的类组织到一起:如果一个类只对一个其他类有用,那么就应该将他们两个组合到一起。

      2提升封装性:考虑这种情况,有两个顶层类,Outer和Inner,Inner需要访问Outer的私有成员。通过把Inner声明为Outer的内部类,那么outer的成员可以声明为private并且Inner可以访问他们。除此Inner本身还对外部世界隐藏。

    3使代码可读性和可维护性更高:将一些较小的类嵌套到顶层类里,让类更靠近其会被使用到的地方。


静态内部类

class OuterClass {

	static class InnerClass {

	}
}

成员内部类

class OuterClass {

	class InnerClass {

	}
}

       与实例方法和变量一样,内部类与包含它的类关联,内部类可以直接访问关联它的类的方法和变量,即内部类包含一个外部类的引用,访问方式为OuterClass.this。由于,内部类关联一个外部类的实例,所以其不能有静态方法,但是其可以有编译时常量(static final)。该常量必须通过字面来赋值。这就可以理解为C语言中的宏的概念,编译时所有使用到static final变量的地方都会被替换为其被赋值的字面量。

注意:为了更好的体会编译时常量,可以看看这个面试题。

     

       为了实例化一个内部类,必须先实例化外部类。如下语法:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

有两种特殊的内部类:在一个方法体里面声明一个内部类即局部类。也可以在一个方法体里面声明一个没有命名的内部类即匿名类


局部内部类

----可以在任何语句块内定义局部类,可以在局部类方法体、for循环和if语句中定义。

----局部类必须是非静态的,因为其能访问外部内实例。

----不能声明一个接口在一个语句块中,接口天然是static的。

----不能在一个局部类中声明静态初始化和静态成员接口。下列代码不能编译通过。编译器产生一个错误:"modifier 'static' is only allowed in constant variable declaration" 

public void sayGoodbyeInEnglish() {
    class EnglishGoodbye {
        public static void sayGoodbye() {
            System.out.println("Bye bye");
        }
    }
    EnglishGoodbye.sayGoodbye();
}


       一个局部类可以有常量变量的静态成员。(常量是一个基本数据类型或者字符串其被声明为final并且被编译时常量初始化,编译时常量通常是一个字符串或者一个算术表达式)如下代码因为 EnglishGoodbye.farewell是一个常量。

  public void sayGoodbyeInEnglish() {
        class EnglishGoodbye {
            public static final String farewell = "Bye bye";
            public void sayGoodbye() {
                System.out.println(farewell);
            }
        }
        EnglishGoodbye myEnglishGoodbye = new EnglishGoodbye();
        myEnglishGoodbye.sayGoodbye();
   	}




匿名内部类

同局部类一样,匿名类能捕获变量;他们对包围类的局部变量有相同访问权限。

----匿名类可以访问外部类的方法。

----匿名类不能访问外围未被声明为final或者effectively final(since 1.8)的局部变量。


匿名类和局部类一样的限制对其成员。

----不能声明静态初始化块和成员接口(接口天然是static)。

----匿名类可以有编译时常量(final static),这个东西就等于写了一个常量,可以将类中所有


在匿名类中可以声明如下项目:

----变量

----方法

----实例初始化块

----局部类

然而要注意的是,不能在匿名类中声明构造函数。


Serialization
Serialization of inner classes, including local and anonymous classes, is strongly discouraged. When the Java compiler compiles certain constructs, such as inner classes, it creates synthetic constructs; these are classes, methods, fields, and other constructs that do not have a corresponding construct in the source code. Synthetic constructs enable Java compilers to implement new Java language features without changes to the JVM. However, synthetic constructs can vary among different Java compiler implementations, which means that .class files can vary among different implementations as well. Consequently, you may have compatibility issues if you serialize an inner class and then deserialize it with a different JRE implementation. See the section Implicit and Synthetic Parameters in the section Obtaining Names of Method Parameters for more information about the synthetic constructs generated when an inner class is compiled.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值