आतील वर्गाचे उदाहरण

AbstractList वर्गात Itr अंतर्गत वर्ग आहे . हे इटरेटर इंटरफेसची अंमलबजावणी आहे , ज्यामुळे संग्रहांचे घटक एक-एक करून मिळवणे शक्य होते:


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();
}

अशाप्रकारे अॅबस्ट्रॅक्टलिस्टच्या कोणत्याही वंशजांना रेडीमेड इटरेटर मिळतो. आणि जर तुम्हाला इटरेटर सानुकूलित करायचा असेल, तर तुम्ही तुमचा स्वतःचा वर्ग लागू करू शकता जो इटरेटर किंवा Itr वारसा घेतो आणि नंतर इटरेटर पद्धत ओव्हरराइड करू शकता. उदाहरणार्थ, ArrayList वर्ग हेच करतो.

Itr वर्ग नॉन-स्टॅटिक आहे . परिणामी, Itr ऑब्जेक्टला AbstractList उदाहरणाचा संदर्भ आहे आणि तो त्याच्या पद्धतींमध्ये प्रवेश करू शकतो ( size , get , remove ).

स्टॅटिक नेस्टेड क्लासचे उदाहरण

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;
    	}
    };
}

पद्धत अनामित वर्गाद्वारे लागू केलेली रिक्त इनपुटस्ट्रीम परत करते. कारण वर्गाला वंशज नसावेत, म्हणून आम्ही ते निनावी केले.

Java Stream API च्या जोडणीसह, निनावी वर्ग सर्वव्यापी बनले आहेत: सर्व लॅम्बडा अभिव्यक्ती निनावी वर्ग आहेत जे काही कार्यात्मक इंटरफेस लागू करतात. काही उदाहरणांचा विचार करा.

AbstractStringBuilder वर्गात प्रसिद्ध StringBuilder आणि StringBuffer वर्गांचे पालक आहेत :


@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);
}

Files क्लासमध्ये Closeable ला Runnable मध्ये रूपांतरित करण्यासाठी आहे :


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(",", "(", ")")));
}