可以在類中的任何位置定義內部類,並在其中編寫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<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;
}
}
上面的程式碼生成以下結果。
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(<argument-list-for-a-superclass-constructor>) {
// Anonymous class body goes here
}
new
運算子用於建立匿名類的範例。它後面是現有的介面名稱或現有的類名稱。介面名稱或類名稱不是新建立的匿名類的名稱。如果使用介面名稱,則匿名類實現介面。如果使用類名,則匿名類繼承自其它類。
僅當新運算子後面跟有類名時,才使用<argument-list>
。 如果新運算子後跟介面名稱,則它為空。
如果<argument-list>
存在,它包含要呼叫的現有類別建構函式的實際引數列表。
匿名類主體像往常一樣在大括號中。匿名類主體應該簡短,以便更好的可讀性。下面的程式碼包含一個簡單的匿名類,它在標準輸出上列印一條訊息。
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.
以下程式碼使用匿名類來建立疊代器(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;
}
}