美文网首页
Java嵌套类

Java嵌套类

作者: wangcanfeng | 来源:发表于2017-06-08 23:20 被阅读0次

嵌套类有四种:静态成员类、非静态成员类、匿名类、局部类。
除了第一种之外,其他三种都是内部类。(EffectiveJava,Item22)

静态成员类(static member class)

静态成员类可以看作是一个普通的类,只是碰巧声明在另一个类的内部而已。

使用static修饰的嵌套类称之为静态成员类,它只能访问外部类的静态成员,不能直接访问外部类的非静态成员。

在静态成员类, 不能访问外部类的非静态成员, 这是由Java语法中"静态方法不能直接访问非静态成员"所限定。

对于外部类来说,整个静态内部类就是外部类成员。类成员只能不能访问类对象属性或方法。

package vlis.myfly.test;

public class StaticMemberClassDemo {
    private int a = 1;
    private int e = 5;
    private static int b = 2;
    
    public void execute(){
        //在外部类中创建成员内部类
        StaticMemberClass staticMemberClass = new StaticMemberClass();
        staticMemberClass.execute();
        
        //不能直接访问内部类成员,包括了非静态成员和静态成员
        //System.out.println(c);
        //System.out.println(d);
        
        System.out.println(staticMemberClass.c);
        System.out.println(StaticMemberClass.d);
        
    }

    private static class StaticMemberClass{// 静态内部类可以用public,protected,private修饰 

        //内部类可以创建与外部类同名的成员变量
        private int a = 1;
        private int c = 3;
        
        private static int b = 2;
        private static int d = 4;

        public void execute(){
            //this引用的是内部类
            System.out.println(this.a);
            
            //在静态内部类中,可以访问到外部类的静态成员
            System.out.println(StaticMemberClassDemo.b);
            
            //不能直接访问外部类的非静态变量
            //System.out.println(e);
            StaticMemberClassDemo staticInner = new StaticMemberClassDemo();
            System.out.println(staticInner);
            System.out.println(staticInner.e);
        }
    }
    
    public static void main(String[] args){
        StaticMemberClassDemo demo = new StaticMemberClassDemo();
        System.out.println(demo);
        demo.execute();
    }
}


非静态成员类(nonstatic member class)

  • 非静态成员类必须依赖于外部类的对象;
  • 在非静态成员类中无法定义静态成员;
  • 非静态成员类对象隐含地保存了一个引用,指向创建它的外部类对象(代码示例中的NonStaticMemberClass.this);
  • 非静态成员类的实例被创建的时候,它和外围实例时间的关联关系也随之被建立起来,而且,这种关联关系以后不能被修改。这种关联关系需要消耗非静态成员类实例的空间,并且增加了构造的时间开销。

Map接口的实现往往使用非静态成员类来实现他的集合视图;Set和List这种集合接口的实现也使用非静态成员类来实现他们的迭代器。

package vlis.myfly.test;

public class NonStaticMemberClassDemo{
    
    private int a = 1;
    static int b = 2;
    
    public void execute(){
        //在外部类中创建成员内部类
        NonStaticMemberClass nonStaticMemberClass = this.new NonStaticMemberClass();
        nonStaticMemberClass.execute();
    }

    public class NonStaticMemberClass{

        //内部类可以创建与外部类同名的成员变量
        private int a = 2;
        
        //NOTE:在非静态内部类中,不能创建静态成员

        public void execute(){
            //this引用的是内部类
            System.out.println(this.a);
            //在非静态内部类中使用外部类的成员变量的方法(MemberInner.this.a)
            //在非静态内部类中,可以访问到外部类的私有成员
            System.out.println(NonStaticMemberClassDemo.this.a);
            //在非静态内部类中,可以访问到外部类的静态成员
            System.out.println(NonStaticMemberClassDemo.b);
        }
    }
    
    public static void main(String[] args){
        NonStaticMemberClassDemo demo = new NonStaticMemberClassDemo();
        demo.execute();
    }
}

静态内部类与非静态内部类的区别

一 . 静态内部类可以有静态成员,而非静态内部类则不能有静态成员。
二 . 静态成员类的非静态成员可以访问外部类的静态变量,而不可访问外部类的非静态变量;
三 . 非静态成员类的实例方法内部,可以调用外围实例上的方法和属性。

如果声明成员类不要求访问外围实例,就要始终把static修饰符放在它的声明中,使它成为静态成员类,而不是非静态成员类。如果省略了static修饰符,则每个实例都会包含一个额外的指向外围对象的引用。这不仅消耗空间和时间,并且会导致外围实例在符合垃圾回收时却仍然保留。(比如HashMap中的Entry静态成员类)

匿名类

匿名类没有名字。它不是外围类的一个成员。它并不与其他的成员一起被声明,而是在使用的同时被声明和实例化。
当且仅当匿名类出现在非静态的环境中时,它才有外围实例。当时即使它出现在静态的环境中,也不可能拥有任何静态成员。

匿名类常见用法:动态的常见函数对象(EffectiveJava,Item21),例如事件监听器;创建过程对象,比如Runnable、Thread或者TimerTask。还有就是静态工厂方法内部,ruturn new XXX();(EffectiveJava,Item18)

局部类

在任何可以声明局部变量的地方,都可以声明局部类,并且局部类也遵守同样的作用域规则。
和匿名类一样,匿名类出现在非静态的环境中时,它才有外围实例。当时即使它出现在静态的环境中,也不可能拥有任何静态成员。

总结:

非静态成员类和静态成员类的使用在于是否每一个嵌套类实例都需要指向其外围实例的引用。
如果一个嵌套类属于一个方法的内部,如果只需要在一个地方创建实例,并且已经有一个预置的类型可以说明这个类的特征,就使用匿名类,否则,使用局部类。

还有一个比较常见的嵌套枚举类

相关文章

  • kotlin 嵌套和内部类

    Kotlin 嵌套类 与Java类似,Kotlin允许您在另一个称为嵌套类的类中定义一个类 由于嵌套类是其封闭类的...

  • Java嵌套类

    嵌套类有四种:静态成员类、非静态成员类、匿名类、局部类。除了第一种之外,其他三种都是内部类。(EffectiveJ...

  • 内部类详解

    Nested Classes in Java嵌套类: 1.The scope of a nested class ...

  • Kotlin内联类、内部类、嵌套类

    Kotlin内联类、内部类、嵌套类 在开始介绍Kotlin内联类、内部类、嵌套类之前,先简要回顾一下java中的内...

  • Java:Java快速入门(下)

    接上篇,咋们继续学习 嵌套类 Java支持如下几种嵌套类: nested class,定义在类型内部的类型。 st...

  • android的api学习翻译一manifest

    1、先看类继承机构 java.lang.Object ---->android.Manifest 2、嵌套类 ...

  • Java嵌套类(Nested Classes)

    在Java中,可以将一个类声明在另一个类的内部,这个类就是嵌套类。嵌套类可以分为两类:静态(static)和非静态...

  • kotlin学习总结之八 类和对象2

    一. 嵌套类 只要将一个类放在另一个类中定义,这个类就变成了嵌套类,相当于Java中static修饰的静态内部类。...

  • Java-嵌套类

    嵌套类分为两类:静态和非静态。被声明static的嵌套类称为静态嵌套类。非静态嵌套类称为内部类。内部类有两种特殊的...

  • java-内部类的创建

    java 创建内部类时离不开他的外围类,除非内部类是嵌套类(即静态内部类),嵌套类中的内部类也是如此 比如: pu...

网友评论

      本文标题:Java嵌套类

      本文链接:https://www.haomeiwen.com/subject/ueoafxtx.html