एक आंतरिक वर्ग का उदाहरण

सार सूची वर्ग में एक आईटीआर आंतरिक वर्ग है। यह इटरेटर इंटरफ़ेस का कार्यान्वयन है , जो संग्रह के तत्वों को एक-एक करके प्राप्त करना संभव बनाता है:

private class Itr implements Iterator<E> {
	int cursor = 0;
	int lastRet = -1;
	int expectedModCount = modCount;

	public boolean hasNext() {
    		return cursor != size();
	}

	public E next() {
    	checkForComodification();
    	try {
        	int i = cursor;
        	E next = get(i);
        	lastRet = i;
        	cursor = i + 1;
        	return next;
    	} catch (IndexOutOfBoundsException e) {
        	checkForComodification();
        	throw new NoSuchElementException(e);
    	}
	}

	public void remove() {
    	if (lastRet < 0)
        	throw new IllegalStateException();
    	checkForComodification();

    	try {
        	AbstractList.this.remove(lastRet);
        	if (lastRet < cursor)
            	cursor--;
        	lastRet = -1;
        	expectedModCount = modCount;
    	} catch (IndexOutOfBoundsException e) {
   	     throw new ConcurrentModificationException();
    	}
	}

	final void checkForComodification() {
    	if (modCount != expectedModCount)
        	throw new ConcurrentModificationException();
	}
}

इसका उपयोग इटरेटर विधि में किया जाता है:

public Iterator<E> iterator() {
	return new Itr();
}

इस प्रकार सारसूची के किसी भी वंशज को तैयार किए गए पुनरावर्तक मिलते हैं। और अगर आपको इटरेटर को कस्टमाइज़ करने की ज़रूरत है, तो आप अपनी खुद की कक्षा को कार्यान्वित कर सकते हैं जो इटरेटर या इटर को प्राप्त करता है , और फिर इटरेटर विधि को ओवरराइड कर सकता है। उदाहरण के लिए, ArrayList वर्ग यही करता है।

ITR क्लास नॉन-स्टैटिक है नतीजतन, आईटीआर ऑब्जेक्ट में सारसूची उदाहरण का संदर्भ होता है और इसकी विधियों ( आकार , प्राप्त , हटाएं ) तक पहुंच सकता है।

एक स्थिर नेस्टेड वर्ग का उदाहरण

Integer क्लास में IntegerCache नेस्टेड क्लास है।

private static class IntegerCache {
	static final int low = -128;
	static final int high;
	static final Integer[] cache;
	static Integer[] archivedCache;

	static {
    	int h = 127;
    	String integerCacheHighPropValue =
        	VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    	if (integerCacheHighPropValue != null) {
        	try {
            	h = Math.max(parseInt(integerCacheHighPropValue), 127);
            	h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
        	} catch( NumberFormatException nfe) {
        	}
    	}
    	high = h;

    	VM.initializeFromArchive(IntegerCache.class);
    	int size = (high - low) + 1;

    	if (archivedCache == null || size > archivedCache.length) {
        	Integer[] c = new Integer[size];
        	int j = low;
        	for(int i = 0; i < c.length; i++) {
            	c[i] = new Integer(j++);
        	}
        	archivedCache = c;
    	}
    	cache = archivedCache;
    	assert IntegerCache.high >= 127;
}

	private IntegerCache() {}
}

IntegerCache कार्यक्षमता को एनकैप्सुलेट करता है जो कैश बनाता है और कैश रेंज के साथ-साथ कैश्ड वैल्यू को भी स्टोर करता है। इस प्रकार, कैश से संबंधित सभी चीजों को एक अलग वर्ग में रखा जाता है। इससे कोड को पढ़ना और संशोधित करना आसान हो जाता है। कोड जो कक्षा का उपयोग करता है:

public static Integer valueOf(int i) {
	if (i >= IntegerCache.low && i <= IntegerCache.high)
    		return IntegerCache.cache[i + (-IntegerCache.low)];
	return new Integer(i);
}

IntegerCache वर्ग गैर-स्थैतिक क्षेत्रों और पूर्णांक वर्ग के तरीकों तक नहीं पहुँचता है । इसके अतिरिक्त, इसे केवल स्टैटिक वैल्यूऑफ़ विधि में एक्सेस किया जाता है। यही है, यह इंटीजर वर्ग के लिए ही बाध्य है , इसके अलग-अलग उदाहरणों के लिए नहीं। और इसका मतलब है कि IntegerCache स्थिर है।

अनाम आंतरिक वर्ग का उदाहरण

अनाम वर्ग के एक उदाहरण के रूप में, आइए InputStream और इसकी स्थिर NullInputStream विधि लें:

public static InputStream nullInputStream() {
    return new InputStream() {
    	private volatile boolean closed;

    	private void ensureOpen() throws IOException {
        	if (closed) {
            		throw new IOException("Stream closed");
        	}
    	}

    	@Override
    	public int available () throws IOException {
        	ensureOpen();
        	return 0;
    	}

    	@Override
    	public int read() throws IOException {
        	ensureOpen();
        	return -1;
    	}

    	@Override
    	public int read(byte[] b, int off, int len) throws IOException {
        	Objects.checkFromIndexSize(off, len, b.length);
        	if (len == 0) {
            		return 0;
        	}
        	ensureOpen();
        	return -1;
    	}

    	@Override
    	public byte[] readAllBytes() throws IOException {
        	ensureOpen();
        	return new byte[0];
    	}

    	@Override
    	public int readNBytes(byte[] b, int off, int len)throws IOException {
        	Objects.checkFromIndexSize(off, len, b.length);
        	ensureOpen();
        	return 0;
    	}

    	@Override
   	 public byte[] readNBytes(int len) throws IOException {
        	if (len < 0) {
            		throw new IllegalArgumentException("len < 0");
        	}
        	ensureOpen();
        	return new byte[0];
    	}

    	@Override
    	public long skip(long n) throws IOException {
        	ensureOpen();
        	return 0L;
    	}

    	@Override
    	public void skipNBytes(long n) throws IOException {
        	ensureOpen();
        	if (n > 0) {
            		throw new EOFException();
        	}
    	}

    	@Override
    	public long transferTo(OutputStream out) throws IOException {
        	Objects.requireNonNull(out);
        	ensureOpen();
        	return 0L;
    	}

    	@Override
    	public void close() throws IOException {
        	closed = true;
    	}
    };
}

विधि एक अज्ञात वर्ग द्वारा कार्यान्वित एक खाली इनपुटस्ट्रीम देता है। क्‍योंकि वर्ग के वंशज नहीं होने चाहिए, इसलिए हमने इसे अनाम बना दिया है।

जावा स्ट्रीम एपीआई के अतिरिक्त, अज्ञात वर्ग सर्वव्यापी हो गए हैं: सभी लैम्ब्डा अभिव्यक्ति अज्ञात कक्षाएं हैं जो कुछ कार्यात्मक इंटरफ़ेस को लागू करती हैं। कुछ उदाहरणों पर गौर कीजिए।

सारस्ट्रिंगबिल्डर क्लास में प्रसिद्ध स्ट्रिंगबिल्डर और स्ट्रिंगबफर कक्षाओं के माता-पिता शामिल हैं:

@Override
public IntStream chars() {
	return StreamSupport.intStream(
        	() -> {
            	byte[] val = this.value;
            	int count = this.count;
            	byte coder = this.coder;
            	return coder == LATIN1
                   	? new StringLatin1.CharsSpliterator(val, 0, count, 0)
                   	: new StringUTF16.CharsSpliterator(val, 0, count, 0);
        	},
        	Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
        	false);
}

फाइल क्लास में क्लोजेबल को रननेबल में बदलने के लिए है :

private static Runnable asUncheckedRunnable(Closeable c) {
	return () -> {
    	try {
        	c.close();
    	} catch (IOException e) {
        	throw new UncheckedIOException(e);
    	}
	};
}

क्लास क्लास में एक विधि का स्ट्रिंग प्रतिनिधित्व प्राप्त करने का एक तरीका है:

private String methodToString(String name, Class<?>[] argTypes) {
	return getName() + '.' + name +
        	((argTypes == null || argTypes.length == 0) ?
        	"()" :
        	Arrays.stream(argTypes)
        	        .map(c -> c == null ? "null" : c.getName())
                	.collect(Collectors.joining(",", "(", ")")));
}