可以在类中的任何位置定义内部类,并在其中编写Java语句。有三种类型的内部类。 内部类的类型取决于位置和声明的方式。

成员内部类

局部内部类

匿名内部类

成员内部类

成员内部类在类中声明的方式与声明成员字段或成员方法相同。它可以声明为public,private,protected或package-level。成员内部类的实例可以仅存在于其封闭类的实例内。

以下代码创建了一个成员内部类。

class Car {
private int year;
// A member inner class named Tire public
class Tire {
private double radius;
public Tire(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
} // Member inner class declaration ends here
// A constructor for the Car class
public Car(int year) {
this.year = year;
}
public int getYear() {
return year;
}
}

局部内在类

一个局部内部类在块中声明。 其范围仅限于声明它的块。由于其范围限于其封闭块,因此其声明不能使用任何访问修饰符,例如public,private或protected。

通常,在方法内定义局部内部类。 但是,它也可以在静态初始化器,非静态初始化器和构造器中定义。下面的代码显示了一个局部内部类的例子。

import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
StringList tl = new StringList();
tl.addTitle("A");
tl.addTitle("B");
Iterator iterator = tl.titleIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
class StringList {
private ArrayList titleList = new ArrayList<>();
public void addTitle(String title) {
titleList.add(title);
}
public void removeTitle(String title) {
titleList.remove(title);
}
public Iterator titleIterator() {
// A local inner class - TitleIterator
class TitleIterator implements Iterator {
int count = 0;
@Override
public boolean hasNext() {
return (count < titleList.size());
}
@Override
public String next() {
return titleList.get(count++);
}
}
TitleIterator titleIterator = new TitleIterator();
return titleIterator;
}
}

上面的代码生成以下结果。

A

B

示例

下面的代码有一个局部内部类继承自另一个公共类。

import java.util.Random;
abstract class IntGenerator {
public abstract int getValue() ;
}
class LocalGen {
public IntGenerator getRandomInteger() {
class RandomIntegerLocal extends IntGenerator {
@Override
public int getValue() {
Random rand = new Random();
long n1 = rand.nextInt();
long n2 = rand.nextInt();
int value = (int) ((n1 + n2) / 2);
return value;
}
}
return new RandomIntegerLocal();
} // End of getRandomInteger() method
}
public class Main {
public static void main(String[] args) {
LocalGen local = new LocalGen();
IntGenerator rLocal = local.getRandomInteger();
System.out.println(rLocal.getValue());
System.out.println(rLocal.getValue());
}
}

上面的代码生成以下结果(每次的结果可能不太一样)。

453673065

1036946998

匿名内部类

匿名内部类没有名称。 因为它没有名称,所以它不能有构造函数。匿名类是一次性类。定义一个匿名类并同时创建它的对象。

创建匿名类及其对象的一般语法如下:

new Interface() {
// Anonymous class body goes here
}

或者 -

new Superclass() {
// Anonymous class body goes here
}

new运算符用于创建匿名类的实例。它后面是现有的接口名称或现有的类名称。接口名称或类名称不是新创建的匿名类的名称。如果使用接口名称,则匿名类实现接口。如果使用类名,则匿名类继承自其它类。

仅当新运算符后面跟有类名时,才使用。 如果新运算符后跟接口名称,则它为空。

如果存在,它包含要调用的现有类的构造函数的实际参数列表。

匿名类主体像往常一样在大括号中。匿名类主体应该简短,以便更好的可读性。下面的代码包含一个简单的匿名类,它在标准输出上打印一条消息。

public class Main {
public static void main(String[] args) {
new Object() {
// An instance initializer
System.out.println("Hello from an anonymous class.");
}
}; // A semi-colon is necessary to end the statement
}
}

上面的代码生成以下结果。

Hello from an anonymous class.

实例-2

以下代码使用匿名类来创建迭代器(Iterator)。

import java.util.ArrayList;
import java.util.Iterator;
public class Main {
private ArrayList titleList = new ArrayList<>();
public void addTitle(String title) {
titleList.add(title);
}
public void removeTitle(String title) {
titleList.remove(title);
}
public Iterator titleIterator() {
// An anonymous class
Iterator iterator = new Iterator() {
int count = 0;
@Override
public boolean hasNext() {
return (count < titleList.size());
}
@Override
public String next() {
return titleList.get(count++);
}
}; // Anonymous inner class ends here
return iterator;
}
}