可以在類中的任何位置定義內(nèi)部類,并在其中編寫Java語句。有三種類型的內(nèi)部類。 內(nèi)部類的類型取決于位置和聲明的方式。
成員內(nèi)部類在類中聲明的方式與聲明成員字段或成員方法相同。它可以聲明為public
,private
,protected
或package-level
。成員內(nèi)部類的實例可以僅存在于其封閉類的實例內(nèi)。
以下代碼創(chuàng)建了一個成員內(nèi)部類。
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;
}
}
一個局部內(nèi)部類在塊中聲明。 其范圍僅限于聲明它的塊。由于其范圍限于其封閉塊,因此其聲明不能使用任何訪問修飾符,例如public
,private
或protected
。
通常,在方法內(nèi)定義局部內(nèi)部類。 但是,它也可以在靜態(tài)初始化器,非靜態(tài)初始化器和構(gòu)造器中定義。下面的代碼顯示了一個局部內(nèi)部類的例子。
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<String> titleList = new ArrayList<>();
public void addTitle(String title) {
titleList.add(title);
}
public void removeTitle(String title) {
titleList.remove(title);
}
public Iterator<String> titleIterator() {
// A local inner class - TitleIterator
class TitleIterator implements Iterator<String> {
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;
}
}
上面的代碼生成以下結(jié)果。
A
B
下面的代碼有一個局部內(nèi)部類繼承自另一個公共類。
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());
}
}
上面的代碼生成以下結(jié)果(每次的結(jié)果可能不太一樣)。
453673065
1036946998
匿名內(nèi)部類沒有名稱。 因為它沒有名稱,所以它不能有構(gòu)造函數(shù)。匿名類是一次性類。定義一個匿名類并同時創(chuàng)建它的對象。
創(chuàng)建匿名類及其對象的一般語法如下:
new Interface() {
// Anonymous class body goes here
}
或者 -
new Superclass(<argument-list-for-a-superclass-constructor>) {
// Anonymous class body goes here
}
new
運算符用于創(chuàng)建匿名類的實例。它后面是現(xiàn)有的接口名稱或現(xiàn)有的類名稱。接口名稱或類名稱不是新創(chuàng)建的匿名類的名稱。如果使用接口名稱,則匿名類實現(xiàn)接口。如果使用類名,則匿名類繼承自其它類。
僅當新運算符后面跟有類名時,才使用<argument-list>
。 如果新運算符后跟接口名稱,則它為空。
如果<argument-list>
存在,它包含要調(diào)用的現(xiàn)有類的構(gòu)造函數(shù)的實際參數(shù)列表。
匿名類主體像往常一樣在大括號中。匿名類主體應(yīng)該簡短,以便更好的可讀性。下面的代碼包含一個簡單的匿名類,它在標準輸出上打印一條消息。
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
}
}
上面的代碼生成以下結(jié)果。
Hello from an anonymous class.
以下代碼使用匿名類來創(chuàng)建迭代器(Iterator
)。
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
private ArrayList<String> titleList = new ArrayList<>();
public void addTitle(String title) {
titleList.add(title);
}
public void removeTitle(String title) {
titleList.remove(title);
}
public Iterator<String> titleIterator() {
// An anonymous class
Iterator<String> iterator = new Iterator<String>() {
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;
}
}