java 内部类、匿名内部类、嵌套类的使用

我们都知道java的类可以由public、default(缺省、不写)来修饰,分别表示的含义是允许公开访问以及只允许包内其它类访问,而同一包内的类通常是为完成同一个功能而协作。

除此之外,我们还会遇到一些类,它们只是其它某个类的实现或组成的一部分,它们不应该被独立的创建出来,当它们创建的时候需要跟"宿体"连在一块,这就是内部类。就好像人类的心脏,你没法单独的new一个出来,它只能依赖于人体而存活(这本来就是它存在的目的),至少现代医学做不到离体存活,现代医学能做的只是把一个心脏取出来,立马换到另外一个人身上。

内部类

内部类通常是宿主类实现的一部分或者是宿主对外提供的一种工具。如果内部类只是为宿主的实现服务,可以将内部类修饰为private,这样也就限制了外部类的访问。而作为工具的内部类,一般访问修饰符为public或default。

为了使用方便,java允许在内部类中直接访问宿主类的成员(这也就决定你没法在宿主类外单独直接new一个内部类对象)。

下面是一个简易的用内部类实现容器迭代器的例子。

interface Selector {
     boolean end();
     Object current();
     void next();
}

public class Sequence {
     private Object[] items;
     private int next = 0;
     public Sequence(int size) {
          items = new Object[size];
     }
     public void add(Object x) {
          if(next < items.length) {
               items[next++] = x;
          }
     }
     private class SequenceSelector implements Selector {
          private int i = 0;
          @Override
          public boolean end() { return i == items.length; }
          @Override
          public Object current() {
               return items[i];
          }
          @Override
          public void next() {
               if( i < items.length ) i++;
          }
     }
     public Selector selector() {
          return new SequenceSelector();
     }
     public static void main(String[] args) {
          Sequence sequence = new Sequence(10);
          for(int i = 0; i < 10;i++) {
               sequence.add(Integer.toString(i));
          }
          Selector selector = sequence.selector();
          while( !selector.end() ) {
               System.out.println(selector.current());
               selector.next();
          }
     }
}

.this和.new

由于内部类可以直接访问宿主类的成员,所以它自身就拥有对宿主类的引用。如果你需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。

public class DotThis {
     void f() {System.out.println("DotThis.f()");}
     public class Inner{
     public DotThis outer() {
          return DotThis.this;
     }
}
public Inner inner() {return new Inner(); };
     public static void main(String[] args) {
          DotThis dt = new DotThis();
          DotThis.Inner dti = dt.inner();
          dti.outer().f();
     }
}

有时你需要创建其某个内部类的对象,而非通过成员方法返回,在这种情况下必须直接使用某个外部类的对象来创建该内部类的对象,使用.new语法。

public class DotNew {
     public class Inner{};
     public static void main(String[] args) {
          DotNew dn = new DotNew();
          DotNew.Inner dni = dn.new Inner();
     }
}

匿名内部类

匿名内部类与内部类最大差异在于,由于它是匿名的,你没法在任意位置,随意的去new这样一个对象,所以它常用于只使用一次的类或者说只在某个地方(方法、对象成员)能new的类,从这个角度来看它是类访问最严格的控制:只在某个位置可以创建类。而内部类至少能在宿主类中随意创建。

匿名内部类支持直接访问所在方法的局部引用,由于引用和基本类型出了方法就无法访问到了,所以要求在匿名内部类中访问的在方法中的外部对象必须是final的。但是,匿名内部类访问的类成员对象不必是final的。

由于匿名类中不可能有命名构造器(因为它根本没有名字),但通过初始化代码段,就能够达到为匿名内部类创建一个构造器的效果。

abstract class Base{
     public Base(int i) {
          System.out.println("Base constructor, i = " + i);
     }
     public abstract void f();
}

public class AnonymousConstructor {
     private static int w = 7;
     public static Base getBase(int i,final int j) {
          return new Base(i) {
               { System.out.println("Inside instance initial"); }
               private int pj = j;
               private int pw = w;
               public void f() {
                    System.out.println("In anonymous f()");
               }
          };
     }
     public static void main(String[] args) {
          Base base = AnonymousConstructor.getBase(47, 39);
          base.f();
     }
}

嵌套类

嵌套类也是定义在一个类中的类,不过它和宿主类除此之外并没有特别直接的关系。在使用形式上,一个内部类用static来修改就成为了一个嵌套类。在嵌套类中你不能直接访问宿主类中的非静态成员。嵌套类在实际工作中,使用很少,既然它跟一个普通类对宿主类的访问权限相似又何必放在一个宿主类中定义呢?而通常嵌套类又允许外部类直接定义该嵌套类的对象,这和普通类也就更相似了。

时间: 2024-11-02 23:27:57

java 内部类、匿名内部类、嵌套类的使用的相关文章

Java中的嵌套类和内部类

以前看<Java编程思想>的时候,看到过嵌套类跟内部类的区别,不过后来就把它们的概念给忘了吧.昨天在看<数据结构与算法分析(Java语言版)>的时候,又遇到了这个概念,当时就很大的疑惑:嵌套类跟内部类有什么区别?只有是否有关键字static的区别吗? 所以今天找了个时间查了一下两者的详细区别,总结在这篇博客中,既方便自己的复习和学习,也启示他人吧. 1,概念: 定义在一个类内部的类,叫作"嵌套类".嵌套类分为两种:static的和非static的.后者又有一个专

Java基础-学习笔记(十)——内部类(嵌套类)

1.内部类的含义 在一个类的内部再定义一个类,就叫做嵌套类.被嵌套的类(内部类)可以直接访问嵌套它的类(外部类)的成员函数和属性,哪怕是私有的.但是反过来就不行,外部的类不能直接访问内部类的成员. 也就是说: 1)内部类可以直接访问外部类的成员 2)外部类不可以直接访问内部类的成员,需要先创建内部类的对象,又该对象来调用内部类的成员和方法. 内部类的定义和普通类没什么区别,不过和外部类不一样的是,它可以被protected和private进行修饰 1 class Outer 2 { 3 int

Java中的嵌套类、内部类、静态内部类

在Java中我们在一个类的内部再定义一个类,如下所示: class OuterClass { ... class NestedClass { ... } } 那么在上面的例子中我们称OuterClass为外围类(enclosing class),里面的那个类称之为嵌套类(Nested Class). 嵌套类可以分为两种,静态的和非静态的,即静态嵌套类和非静态嵌套类.非静态嵌套类又叫做内部类(Inner Class).我们通常所说的静态内部类其实是不严格的,严格的说应该叫做静态嵌套类(Static

JAVA内部类与异常类

内部类 定义 在类A中声明了类B,B称为内部类,A称为B的外嵌类 应用 需要建立一个类,不想它为外界所用 public class RedCowform{ static String formName = "红牛农场"; Redcow cow;// 声明 public RedCowform(){ cow = new RedCow(); } class RedCow{ String Name; int height,weight,price; RedCow(){ //赋值 可以使用外嵌类

Java嵌套类,内部类和外部类

1.嵌套类,内部类 嵌套类是指被定义在一个类内部的类: JAVA的嵌套类有很多种类:1.静态成员类:2.非静态成员类:3.匿名类:4.局部类:其中,除了静态成员类之外,其他的都是内部类,因为静态成员类更像是一个独立的类: 但是静态成员类,是外部类内部的一个成员,静态成员类的访问和其他的静态成员一样:1.通过外部类类名调用:2.如果静态成员类定义为私有,那么只能在外部类内部使用        JAVA 内部类可以很好的实现隐藏,并且内部类拥有外围类的所有元素的访问权限,可是实现多重继承,并且可以避

java嵌套类(Nested&amp;nbsp;Classes)总结

转自:http://www.cnblogs.com/aigongsi/archive/2012/04/24/2467183.html Nested Classes定义 在java语言规范里面,嵌套类(Nested Classes)定义是: A nested class is any class whose declaration occurs within the body of another class or interface. A top level class is a class t

spring 笔记1: mvn 中Controller方法的参数不能是嵌套类(内部类)。

最近做spring开发,个人认为,Controller和客户端js通讯时传递的参数类 只使用某几个方法,为了减少对其他功能的影响,想把参数类定义为Controller类的 嵌套类(内部类).但是实践发现不行. 系统会报错: Servlet.service() for servlet [kingkoo] in context with path [] threw exception [Request processing failed; nested exception is org.spring

Java内部类的使用小结

内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态static的,也可用public,default,protected和private修饰.(而外部顶级类即类名和文件名相同的只能使用public和default). 注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类.对于一个名为outer的外部类和其内部定义的名为inner的内部类.编译完成后出现outer.class和outer$inner.class两类.所以内部类的成员变量/方法名可

Java内部类的使用小结 形参为什么要用final

部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态static的,也可用public,default,protected和private修饰.(而外部顶级类即类名和文件名相同的只能使用public和default). 注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类.对于一个名为outer的外部类和其内部定义的名为inner的内部类.编译完成后出现outer.class和outer$inner.class两类.所以内部类的成员变量/方法名可以

Java内部类的使用小结(转)

内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态static的,也可用public,default,protected和private修饰.(而外部顶级类即类名和文件名相同的只能使用public和default). 注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类.对于一个名为outer的外部类和其内部定义的名为inner的内部类.编译完成后出现outer.class和outer$inner.class两类.所以内部类的成员变量/方法名可