`

Java内部类(Inner Class)

阅读更多
简单的说,内部(inner)类指那些类定义代码被置于其它类定义中的类;而对于一般的、类定义代码不嵌套在其它类定义中的类,称为顶层(top-level)类。对于一个内部类,包含其定义代码的类称为它的外部(outer)类。
<!--[if !supportLists]-->1          <!--[endif]-->Static member class(静态成员类)

类声明中包含“static”关键字的内部类。如以下示例代码,

Inner1/Inner2/Inner3/Inner4就是Outer的四个静态成员类。静态成员类的使用方式与一般顶层类的使用方式基本相同。


public class  Outer{
    //just like static method, static member class has public/private/default access privilege levels
    
    //access privilege level: public 
    public static class Inner1 {
        public Inner1() {
            //Static member inner class can access static method of outer class
            staticMethod();    
            //Compile error: static member inner class can not access instance method of outer class
            //instanceMethod();  
        }
    }
    
    //access privilege level: default 
    static class Inner2 {
        
    }
    
    //access privilege level: private 
    private static class Inner3 {
        //define a nested inner class in another inner class 
        public static class Inner4 {    
        }
    }

    private static void staticMethod() {
        //cannot define an inner class in a method
        /*public static class Inner4() {
        }*/
    }
    
    private void instanceMethod() {
        //private static member class can be accessed only in its outer class definition scope
        Inner3 inner3 = new Inner3();
        //how to use nested inner class
        Inner3.Inner4 inner4 = new Inner3.Inner4();
    }
}

class Test {
    Outer.Inner1 inner1 = new Outer.Inner1();
    //Test and Outer are in the same package, so Inner2 can be accessed here
    Outer.Inner2 inner2 = new Outer.Inner2(); 
    //Compile error: Inner3 cannot be accessed here
    //Outer.Inner3 inner3 = new Outer.Inner3(); 
}



<!--[if !supportLists]-->1.1      <!--[endif]-->静态成员类特性

    * 静态成员类可访问外部类的任一静态字段或静态方法
    * 像静态方法或静态字段一样,静态成员类有public/private/default权限修饰符

<!--[if !supportLists]-->1.2      <!--[endif]-->静态成员类约束

    * 静态成员类不能与外部类重名
    * 像外部类的静态方法一样,不能直接访问外部类的实例字段和实例方法
    * 静态成员类只能定义于外部类的顶层代码或外部类其它静态成员类的顶层代码中(嵌套定义);不能定义于外部类的某个函数中。

<!--[if !supportLists]-->1.3      <!--[endif]-->新增语法

    如示例代码所示,可以以“OuterClass.InnerClass”的方式来引用某个内部类。
<!--[if !supportLists]-->1.4      <!--[endif]-->什么时候使用静态成员类

B为A的辅助类,且只为A所用时,可将B定义为A的静态成员类。例如JDK中的LinkedList类就有Entry静态成员类:
public class LinkedList<E> extends AbstractSequentialList<E> 
   …;
   private static class Entry<E> {
    E element;
    Entry<E> next;
    Entry<E> previous;

    Entry(E element, Entry<E> next, Entry<E> previous) {
        this.element = element;
        this.next = next;
        this.previous = previous;
    }
    }
    …;
}


   显然,Entry用来表示LinkedList中的一个结点,只被LinkedList自身使用。


<!--[if !supportLists]-->2          <!--[endif]-->Member class(成员类)

一个静态成员类,若去掉“static”关键字,就成为成员类。如下示例代码,Inner1/Inner2/Inner3/Inner4就是Outer的四个成员类

public class Outer {
    //just like instance method, member class has public/private/default access privilege levels
    private int data;
    
    //access privilege level: public 
    public class Inner1 {
        private int data;
        private int data1;
        public Inner1() {
            //member class can access its outer class' instance field directly
            data1 = 1;
            //itself data field
            data = 1;
            //its outer class instance field
            Outer.this.data = 1;
        }
    }
    
    //access privilege level: default
    class Inner2 {
        //can not define static filed, method, class in member class
        //static int j = 1;
        
        //but, "static final" compound is allowed 
        static final int CONSTANT = 1;
    }
    
    //access privilege level: private 
    private class Inner3 {
        public class Inner4 {
            
        }
    }
    
    //in fact, Inner5 is not a member class but a static member class
    interface Inner5 {
    }
    
    private static void staticMethod() {
        //can not create a member class instance directly in outer class' static method
        //Inner1 inner1 = new Inner1();
    }
    
    private void instanceMethod() {
        //can create a member class instance in outer class' instance method
        Inner1 inner1 = new Inner1();
    }
}

class Test {
    public Test() {
        //cannot create member class instance directly in class other than outer class
        //Outer.Inner2 inner2 = new Outer.Inner2();
        
        //create a member class instance outside it's outer class
        Outer outer = new Outer();
        Outer.Inner1 inner1 = outer.new Inner1();
    }
}

 



<!--[if !supportLists]-->2.1      <!--[endif]-->成员类特性

<!--[if !supportLists]-->·        <!--[endif]-->类似于外部类的实例函数,成员类有public/private/default权限修饰符

<!--[if !supportLists]-->·        <!--[endif]-->一个成员类实例必然所属一个外部类实例,成员类可访问外部类的任一个实例字段和实例函数。
<!--[if !supportLists]-->2.2      <!--[endif]-->成员类约束

    * 成员类不能与外部类重名
    * 不能在成员类中定义static字段、方法和类(static final形式的常量定义除外)。因为一个成员类实例必然与一个外部类实例关联,这个static定义完全可以移到其外部类中去
    * 成员类不能是接口(interface)。因为成员类必须能被某个外部类实例实例化,而接口是不能实例化的。事实上,如示例代码所示,如果你以成员类的形式定义一个接口,该接口实际上是一个静态成员类,static关键字对inner interface是内含(implicit)的。

<!--[if !supportLists]-->2.3      <!--[endif]-->新增语法

    一个成员类实例必然所属于其外部类的一个实例,那么如何在成员类内部获得其所属外部类实例呢?如示例代码所示,采用“OuterClass.this”的形式。
<!--[if !supportLists]-->2.4      <!--[endif]-->指定内部类实例所属的外部类实例

内部类实例可在其外部类的实例方法中创建,此新创建内部类实例所属的外

部类实例自然就是创建它的外部类实例方法对应的外部类实例。

          另外,如示例代码所示,对于给定的一个外部类实例outerClass,可以直接创建其内部类实例,语法形式为:

OuterClass.InnerClass innerClass = outerClass.new InnerClass();

<!--[if !supportLists]-->
2.5      <!--[endif]-->什么时候使用成员类

     成员类的显著特性就是成员类能访问它的外部类实例的任意字段与方法。方便一个类对外提供一个公共接口的实现是成员类的典型应用。

       以JDK Collection类库为例,每种Collection类必须提供一个与其对应的Iterator实现以便客户端能以统一的方式遍历任一Collection实例。每种Collection类的Iterator实现就被定义为该Collection类的成员类。例如JDK中AbstractList类的代码片断:

 
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    private class Itr implements Iterator<E> {
         ………;
    }

     public Iterator<E> iterator() {
        return new Itr();
     }
}



    因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。

    试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。
<!--[if !supportLists]-->3          <!--[endif]-->Local class(局部类)

对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类

的静态方法或静态初始化代码段中就成为了局部静态成员类。

       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。

       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。

       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。

另外,局部类也有其自己的特性,如以下代码所示:




<!--[if !supportLists]-->3.1      <!--[endif]-->局部类特性

如示例代码所示,局部类能且只能访问其所属代码段中的声明为final的局部

变量。为什么只能访问声明为final的局部变量呢?我们知道,局部变量在其所属的代码段(譬如某个函数)执行完毕后就会被回收,而一个局部类的实例却可以在其类定义所属代码段执行完毕后依然存在,如果它可操控非final的局部变量,用户就可以通过该实例修改已不存在的局部变量,无意义。
<!--[if !supportLists]-->3.2      <!--[endif]-->局部类约束

    * 如示例代码所示,内部类只在定义它的代码段中可见,不能在它所属代码段之外的代码中使用;因此也就没有public/private/default权限修饰符(无意义)
    * 不能以局部类形式定义一个接口。局部类只在其所属代码段中可见,定义这样的接口无意义
    * 局部类类名不能与其外部类类名重复

<!--[if !supportLists]-->3.3      <!--[endif]-->什么时候使用局部类

局部类大部分以匿名类的形式使用。

          
<!--[if !supportLists]-->4          <!--[endif]-->Anonymous class(匿名类)

没有类名的局部类就是匿名类。用一条语句完成匿名类的定义与实例创建。例

如如下代码:
public class Outer {
    public void instanceMethod() {
        //define a nonymous class which implements Action interface and creat an instance of it
        Action action = new Action() {
            public void doAction() {
                System.out.println("a simple anonymous class demo");
            }};
        action.doAction();
        
        //define a nonoymous class which extends BaseClass and create an instance of it
        new BaseClass(5) {
            public void printData(){
                System.out.println("data = " + getData());
            }
        }.printData(); //"data = 5" will be outputed
    }
}

interface Action {
    void doAction();
}

class BaseClass {
    private int data;
    
    public BaseClass (int data) {
        this.data = data;
    }
    
    public int getData() {
        return data;
    }
}


<!--[if !supportLists]-->4.1      <!--[endif]-->匿名类特性与约束

匿名类是一种特殊的局部类。局部类的特性与约束都适用与它。
<!--[if !supportLists]-->4.2      <!--[endif]-->新增语法
<!--[if !supportLists]-->4.2.1      <!--[endif]-->继承自某个基类的匿名类

new class-name ( [ argument-list ] ) { class-body }



创建匿名类实例时,“argument-list”将被传入其基类(即class-name)对应的构造函数。
<!--[if !supportLists]-->4.2.2      <!--[endif]-->实现某个接口的匿名类

new interface-name () { class-body }


<!--[if !supportLists]-->
4.3      <!--[endif]-->什么时候使用匿名类

    * 该类定义代码段很短
    * 只需要创建该类的一个实例
    * 类的定义代码与类的使用代码紧邻
    * 使用匿名不影响代码的易读性

譬如,如下实现类似与c的callback功能的代码就是匿名类的典型应用:


File f = new File("/src");      // The directory to list

// Now call the list() method with a single FilenameFilter argument
// Define and instantiate an anonymous implementation of FilenameFilter
// as part of the method invocation expression.
String[] filelist = f.list(new FilenameFilter() {
  public boolean accept(File f, String s) { return s.endsWith(".java"); }
}); // Don't forget the parenthesis and semicolon that end the method call!

public class Outer {
    private int instanceField; 
    private static int staticField; 
    
    //define a local member class in instance code block
    {
        int localVirable1 = 0;
        final int localVirable2 = 1;
        class Inner1 {
            public Inner1() {
                //can access its outer class' field and method directly
                instanceField = 1;
                //use OuterClass.this to get its corresponding outer class instance
                Outer.this.instanceField = 1;
                
                //can not access the not final local virable in its containing code block
                //System.out.print(localVirable1);
                
                //can access the final local virable in its containing code block
                System.out.print(localVirable2);
            }
        }        
        
        //local class can not have privilege modifier 
        /*public class inner2 {            
        }*/
    }
    
    // define a local static member class in static code block
    static {
        class Inner2 {
            public Inner2() {
                staticField = 1;
                //can not access instance field and method in a local static member class 
                //intanceField = 2;
            }
        }
    }
    
    public void intanceMethod() {
        //define a local class in its out class' instance method
        class Inner3 {
        }
        
        //local class is visible only in its containning code block
        //Outer.Inner2 inner2;
    }
    
    private static void staticMethod() {
        //define a local static member class in its out class' static method
        class Inner4 {    
            public Inner4() {
                staticField = 2;
            }
        }
        
        //can not define a interface as a local class
        /*interface I {
        }*/
    }
}
分享到:
评论

相关推荐

    Java中inner_class内部类

    1. 对于成员内部类和静态嵌套类,可以通过`new OuterClass().new InnerClass()`或`OuterClass.InnerClass inner = new OuterClass().new InnerClass();`来实例化。 2. 局部内部类和匿名内部类只能在定义它们的方法...

    java-内部类(InnerClass)详解.pdf

    可以通过"OuterClass.InnerClass"的方式引用静态成员类,如`new Outer.Inner1()`。 6. **使用场景** - 当需要创建一个与外部类紧密相关的辅助类,并且希望这个类在没有外部类实例的情况下也能存在时,可以使用...

    Java内部类(innerclass).docx

    ### Java内部类详解 #### 一、嵌套类概述 在Java编程中,嵌套类是一种重要的面向对象设计工具,它允许程序员在一个类的内部定义另一个类。这种特性极大地增强了Java语言的灵活性和封装能力。 #### 二、嵌套类分类...

    java_innerclass_instance.rar_innerclass

    在“java_innerclass_instance.rar_innerclass”这个压缩包中,包含的资源可能是一个关于Java内部类实例应用的示例代码。 内部类主要有四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。这里我们主要...

    java内部类详解

    创建静态内部类的实例时,无需先创建外部类的实例,而是通过外部类名直接创建,如 `OuterClass.InnerClass inner = new OuterClass.InnerClass();`。 2. 成员内部类(Member Inner Class) 成员内部类不带 `static...

    java易混淆概念Anonymous Inner Class

    Anonymous Inner Class (匿名内部类) 是否可以 extends(继承)其它类?匿名内部类是没有名字的内部类。不能 extends(继承)其它类,但一个内部类可以作为一个接口,由另一个内部类实现。 final 修饰符(关键字)...

    java内部类使用例子

    Java内部类是Java语言提供的一种独特特性,它允许我们在一个类的定义内部定义另一个类。这种内部类可以是成员内部类、局部内部类、匿名内部类或静态内部类,每种都有其特定的用途和使用场景。在这个"java内部类使用...

    第11章 内部类(Inner class).ppt

    内部类(Inner Class)是Java语言中一个独特的特性,它允许在一个类的内部定义另一个类。这种设计模式在处理特定问题时提供了更大的灵活性,比如实现事件监听器、封装复杂逻辑或者创建私有的辅助类。本章我们将深入...

    Java内部类总结

    ### Java内部类总结 在Java编程语言中,内部类是一个重要的概念,它允许开发者在一个类的内部定义另一个类。这种特性极大地增强了代码的封装性和复用性,同时也为解决特定问题提供了灵活的方法。本文将围绕Java内部...

    Java 内部类

    在这个例子中,`InnerClass` 是 `OuterClass` 的成员内部类,它可以访问 `outerField` 这个私有字段。 二、方法内部类 方法内部类,也称为局部内部类,是在一个方法内部定义的类。它们的作用域仅限于该方法,因此...

    Java语法总结 - 内部类

    Java内部类详解 Java内部类是Java语言中的一种特殊类别,它是指定义在另外一个类内部的类。内部类可以访问外部类的所有成员变量和方法,包括私有的变量和方法。内部类可以分为四种:成员内部类、静态嵌套类、方法...

    java-嵌套类(inner class)-来自oracle官网

    嵌套类主要分为两大类:静态嵌套类(Static Nested Class)和非静态嵌套类(Non-static Nested Class),后者通常被称为内部类(Inner Class)。 - **静态嵌套类**:此类嵌套类被声明为`static`,因此它们与外部类...

    JAVA 内部类 PPT

    Java内部类是Java语言的一个独特特性,它允许我们在一个类的内部定义另一个类。这种设计提供了更高级别的封装和组织代码的方式。以下是关于内部类及其相关知识点的详细说明: 1. **内部类基本语法** - **实例内部...

    java 内部类 局部内部类 匿名类 实例代码

    Java内部类是Java语言特性中一个独特而强大的部分,它允许在一个类的内部定义另一个类。内部类可以访问外部类的所有成员,包括私有成员,这使得内部类在实现某些特定设计模式时非常有用。本篇文章将深入探讨Java中的...

    java 内部类应用

    Java内部类是Java语言的一个特色特性,它允许我们在一个类的内部定义另一个类。这种设计模式在处理一些特定情况时非常有用,例如实现匿名回调、封装特定逻辑或创建与外部类有紧密关系的类。本篇文章将深入探讨Java...

    Java面向对象(高级)- 类的成员之五:内部类(InnerClass)

    Java面向对象(高级)-- 类的成员之五:内部类(InnerClass)

    java 内部类的实例详解

    Java内部类是Java语言中一个独特且强大的特性,它允许在一个类的定义内定义另一个类。内部类可以分为四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。下面我们将深入探讨内部类的使用方法和优势。 首先...

    JAVA内部类总结

    ### JAVA内部类总结 在Java编程语言中,内部类(Inner Classes)是一种非常重要的特性,它允许我们在一个类的内部定义另一个类。这种结构不仅能够提高代码的组织性,还能帮助我们更好地处理类与类之间的关系。根据...

Global site tag (gtag.js) - Google Analytics