`
newleague
  • 浏览: 1502463 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

Java内部类(InnerClass)详解

 
阅读更多

简单的说,内部(inner)类指那些类定义代码被置于其它类定义中的类;而对于一般的、类定义代码不嵌套在其它类定义中的类,称为顶层(top-level)类。对于一个内部类,包含其定义代码的类称为它的外部(outer)类。
1          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(); 
}
 

1.1      静态成员类特性

静态成员类可访问外部类的任一静态字段或静态方法

像静态方法或静态字段一样,静态成员类有public/private/default权限修饰符

1.2      静态成员类约束

静态成员类不能与外部类重名

像外部类的静态方法一样,不能直接访问外部类的实例字段和实例方法

静态成员类只能定义于外部类的顶层代码或外部类其它静态成员类的顶层代码中(嵌套定义);不能定义于外部类的某个函数中。

1.3      新增语法
    如示例代码所示,可以以“OuterClass.InnerClass”的方式来引用某个内部类。
1.4      什么时候使用静态成员类
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自身使用。
2          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();
    }
}
 
 
2.1      成员类特性
·        类似于外部类的实例函数,成员类有public/private/default权限修饰符
·        一个成员类实例必然所属一个外部类实例,成员类可访问外部类的任一个实例字段和实例函数。
2.2      成员类约束

成员类不能与外部类重名

不能在成员类中定义static字段、方法和类(static final形式的常量定义除外)。因为一个成员类实例必然与一个外部类实例关联,这个static定义完全可以移到其外部类中去

成员类不能是接口(interface)。因为成员类必须能被某个外部类实例实例化,而接口是不能实例化的。事实上,如示例代码所示,如果你以成员类的形式定义一个接口,该接口实际上是一个静态成员类,static关键字对inner interface是内含(implicit)的。

2.3      新增语法
    一个成员类实例必然所属于其外部类的一个实例,那么如何在成员类内部获得其所属外部类实例呢?如示例代码所示,采用“OuterClass.this”的形式。
2.4      指定内部类实例所属的外部类实例
内部类实例可在其外部类的实例方法中创建,此新创建内部类实例所属的外
部类实例自然就是创建它的外部类实例方法对应的外部类实例。
          另外,如示例代码所示,对于给定的一个外部类实例outerClass,可以直接创建其内部类实例,语法形式为:
OuterClass.InnerClass innerClass = outerClass.new InnerClass();

2.5      什么时候使用成员类
     成员类的显著特性就是成员类能访问它的外部类实例的任意字段与方法。方便一个类对外提供一个公共接口的实现是成员类的典型应用。
       以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开放额外的访问接口。
3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

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 {
        }
*/
    }
}

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

如示例代码所示,内部类只在定义它的代码段中可见,不能在它所属代码段之外的代码中使用;因此也就没有public/private/default权限修饰符(无意义)

不能以局部类形式定义一个接口。局部类只在其所属代码段中可见,定义这样的接口无意义

局部类类名不能与其外部类类名重复

3.3      什么时候使用局部类
局部类大部分以匿名类的形式使用。
           
4          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;
    }
}
4.1      匿名类特性与约束
匿名类是一种特殊的局部类。局部类的特性与约束都适用与它。
4.2      新增语法
4.2.1      继承自某个基类的匿名类

new class-name ( [ argument-list ] ) { class-body }
 
创建匿名类实例时,“argument-list”将被传入其基类(即class-name)对应的构造函数。
4.2.2      实现某个接口的匿名类
new interface-name () { class-body }

4.3      什么时候使用匿名类

该类定义代码段很短

只需要创建该类的一个实例

类的定义代码与类的使用代码紧邻

使用匿名不影响代码的易读性

譬如,如下实现类似与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!

分享到:
评论

相关推荐

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

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

    java内部类详解

    Java 内部类详解 Java 内部类是一种高级特性,允许在一个类的定义内部创建另一个类。这种设计模式提供了更灵活的代码组织方式,同时还可以实现特定的封装和访问控制。内部类主要分为四种类型:静态内部类、成员内部...

    Java内部类(innerclass).docx

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

    java 内部类的实例详解

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

    Class详解内部类等

    在Java编程语言中,内部类(也称为嵌套类)是一种强大的工具,它可以提高代码的组织性和可读性。内部类可以直接访问外部类的所有成员,包括私有(private)成员,这使得它们在处理封装和实现特定逻辑时非常有用。...

    Java语法总结 - 内部类

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

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

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

    Java内部类详解.pdf

    例如,`outClassInstance.new InnerClass()`会创建一个新的`InnerClass`实例,关联到`outClassInstance`。请注意,`.new`操作必须使用外围类的实例,而不是类本身。 4. **类型和作用域**: - 静态内部类(也称为...

    Java内部类

    ### Java内部类详解 在Java编程语言中,内部类(Inner Class)是一种非常重要的概念,它使得类的设计更加灵活和高效。本文将详细介绍Java内部类的相关知识点,包括其定义、分类以及应用场景等。 #### 一、Java内部...

    Java内部类(DOC)

    ### Java内部类(DOC)详解 #### 一、概述 Java内部类是Java语言中一个重要的概念,它指的是那些类定义被嵌套在其他类定义中的类。与之相对应的是顶层类,即那些类定义没有被嵌套在其他类中的类。内部类又可以...

    Java内部类访问规则.doc

    ### Java内部类访问规则 #### 一、内部类概述与定义原则 在Java编程中,内部类(Inner Class)是一种特殊类型的类,它被定义在另一个类(外部类)的内部。内部类的一个主要用途是在描述一个外部类的对象时能够包含...

    浅谈Java内部类的四个应用场景

    ### 浅谈Java内部类的四个应用场景 #### 一、引言 在Java语言中,内部类(Inner Class)作为一种特殊的存在,为开发者提供了更为灵活的面向对象编程方式。通过本文,我们将深入探讨Java内部类的四个典型应用场景,...

    Java内部类总结

    ### Java内部类详解 #### 一、什么是内部类? 内部类,顾名思义,是在另一个类的内部定义的类。这种独特的结构让内部类能够访问包含它的外部类的私有成员,包括变量和方法。这为Java程序员提供了一种灵活的方式来...

    java静态内部类(嵌套类)

    ### Java静态内部类(嵌套类)详解 #### 一、静态内部类概念与特性 在Java编程语言中,静态内部类(也被称为嵌套类)是一种特殊的内部类形式,它通过`static`关键字来定义。与普通内部类相比,静态内部类具有以下...

    JAVA 内部类详解及实例

    Java 内部类详解及实例 Java 内部类是一种特殊类型的类,它定义在一个类的内部。这种设计模式在 Java 中提供了许多便利,比如封装、抽象和代码复用。以下将详细介绍内部类的种类、特性以及如何使用它们。 1. 成员...

    Java面试题,他会给你很好的Java面试准备,第一,谈谈final, finally, finalize的区别,第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?

    另外,在Java面试中,Anonymous Inner Class(匿名内部类)也是一个重要的知识点。匿名内部类是没有名字的内部类。不能extends(继承)其它类,但一个内部类可以作为一个接口,由另一个内部类实现。 在Java中,还有...

    Java软件开发实战 Java基础与案例开发详解 8-1 内部类与包装器 共15页.pdf

    ### Java软件开发实战:内部类与包装器 #### 8-1 内部类与包装器 ##### 内部类概述 ...以上内容涵盖了Java内部类和包装器的基础概念及其具体应用,希望能够帮助您更好地理解和掌握这些重要的Java概念。

    JAVA语法总结 - 内部类

    内部类(Inner Class)自Java 1.1版本引入以来,一直是Java编程语言中的一个重要特性。它允许开发者在一个类的内部定义另一个类,这有助于更好地组织代码并实现更紧密的封装。 #### 二、内部类的分类及特点 内部类...

Global site tag (gtag.js) - Google Analytics