Java嵌套类(nested class)----静态成员类、非静态成员类、匿名类和局部类

这四个修饰符的访问权限如下表: 
----------------------------------------------- 
                      类内部     package内       子类         其他 
public             允许         允许                 允许         允许 
protected       允许         允许                 允许         不允许 
default           允许         允许                 不允许     不允许 
private           允许         不允许             不允许     不允许 

------------------------------------------------------------------------------------------

嵌套类:指被定义在另一个类的内部的类。它存在的目的只是为它的外围类提供服务。
嵌套类有4种:静态成员类、非静态成员类、匿名类和局部类。优先用静态成员类
内部类有3种  非静态成员类、匿名类和局部类。内部类中不能定义任何静态的东西

  1.内部类是定义在另一个类中的类。 内部类在封装它的类中使用跟普通类一样。 在其他地方使用必须在new前面冠以外部类对象。 即:外部对象名.new 内部类(参数)
  2.内部类可以访问外部类的所有成员,包括private属性。
  3.在内部类中this.方法及字段指向内部类; 外部类.this方法及字段指向外部类
  4.用static修饰内部类 则该内部类实际是一种外部类。 创建时可以用new 外部类.内部类()

1.静态成员类

public class Main{
    public static class NestClass{}
}
//在外面使用时候形式如下,在Main中使用则不需要加上外部类限定
Main.NestClass nestClass = new Main.NestClass();

2.非静态成员类

  非静态成员类:在类里面,但不在块、构造器、方法里面。
public class Main{
    public class MemberClass{}
 }
静态和非静态的之前唯一的区别是,静态成员类的声明中包含static

3.匿名类

匿名类相当于在定义类的同时再新建这个类的实例。我们来看看匿名类的编译结果。
这个类的代码如下:

public class Test {  
  public void test() {  
    Runnable r = new Runnable(){  
      @Override  
      public void run(){  
        System.out.println("hello");  
      }  
    };  
  }  
}
    来看看它的编译结果,通过 javap反向编译Test.class,得到的结果如下:
SourceFile: "Test.java"  
EnclosingMethod: #20.#21                // Test.test  
InnerClasses:  
     #6; //class Test$1
    发现了一个字段叫EnclosingMethod,说明这个类是定义在Test.test方法下的。那现在有个问题,如果有两个test方法,会出现什么呢?
    原来是旁边这个注释不太准确,实际上会包含函数签名的。请看Constant Pool部分,这里的#21指向了这个函数签名。
#21 = NameAndType        #34:#16        // test:()V


3.1.匿名类的语法
这里举一个简单的例子:

Runnable hello = new Runnable() {  
    public void run() {  
        System.out.println("hello");  
    }  
};
一个匿名类由以下几个部分组成:
  1).new操作符
  2).Runnable:接口名称。这里还可以填写抽象类、普通类的名称。
  3).():这个括号表示构造函数的参数列表。由于Runnable是一个接口,没有构造函数,所以这里填一个空的括号表示没有参数。
  4).{...}:大括号中间的代码表示这个类内部的一些结构。在这里可以定义变量名称、方法。跟普通的类一样。

    注意:匿名类没有名字,它不是外围类的一个成员,它并不与其他的成员一起被声明,而是只能在使用的同时被声明和实例化。可以出现在代码中任何允许存在表达式的地方。当且仅当匿名类出现在非静态的环境中,它才有外围实例,但它不可能拥有任何静态成员。你不能执行instanceof测试。

3.2.访问权限
那么匿名内部类能访问哪些东西呢?按照规则, 可以访问如下内容
  1).访问外层Class里面的字段。
  2).不能访问外层方法中的本地变量。除非变量是final。
  3).如果内部类的名称和外面能访问的名称相同,则会把名称覆盖掉。

匿名类中可以包含的东西有:字段、方法、实例初始化代码、本地类


匿名类里面不可以有的东西
    1.不能定义静态初始化代码块(Static Initializer)。比如下面的代码是不符合语法的:

public class A {  
    public void test() {  
        Runnable r = new Runnable() {  
            static { System.out.println("hello"); }  
        };  
    }  
}
  2.不能在匿名类里面定义接口。
比如:
public class A {  
    public void test() {  
        Runnable r = new Runnable() {  
            public interface Hello { };  
        };  
    }  
}
和上面一样,也是为了语义的清晰。interface只能定义静态的。
3.不能在匿名类中定义构造函数。

public class A {  
    public void test() {  
        Runnable r = new Runnable() {  
            public Runnable() { }  
        };  
    }  
}
因为匿名类没有名字,而构造函数需要把类名作为方法名才能看成构造函数。

4、局部类

局部类:是四种嵌套类中用得最少的类。在一个方法中定义的。在任何“可以声明局部变量”的地方,都可以声明局部类。
  1.同局部变量,局部类不能用public,private,protected,static修饰,但可以被final或者abstract修饰。
  2.可以访问其外部类的成员
  3.不能访问该方法的局部变量,除非是final局部变量。

public class Test {
    {
        class AA{}//块内局部类
    }
    public Test(){
        class AA{}//构造器内局部类
    }
    public static void main(String[] args){
    }
    public void test(){
        class AA{}//方法内局部类
    }
}
//注意到了吧,可以同名,编译后,形成诸如:外部类名称+$+同名顺序+局部类名称
//Test$1AA.class/Test$2AA.class/Test$3AA.class










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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值