உள் வகுப்பின் எடுத்துக்காட்டு

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 பொருள் சுருக்கப்பட்டியல் நிகழ்வின் குறிப்பைக் கொண்டுள்ளது மற்றும் அதன் முறைகளை அணுகலாம் ( அளவு , பெறு , அகற்று ).

நிலையான உள்ளமை வகுப்பின் எடுத்துக்காட்டு

முழு எண் வகுப்பில் 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;
    	}
    };
}

இந்த முறை ஒரு அநாமதேய வகுப்பினால் செயல்படுத்தப்பட்ட வெற்று InputStream ஐ வழங்குகிறது. வகுப்பிற்கு சந்ததிகள் இருக்கக் கூடாது என்பதால், அதை அநாமதேயமாக்கினோம்.

ஜாவா ஸ்ட்ரீம் ஏபிஐ சேர்ப்பதன் மூலம், அநாமதேய வகுப்புகள் எங்கும் காணப்படுகின்றன: அனைத்து லாம்ப்டா வெளிப்பாடுகளும் சில செயல்பாட்டு இடைமுகத்தை செயல்படுத்தும் அநாமதேய வகுப்புகள். சில உதாரணங்களைக் கவனியுங்கள்.

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

க்ளோஸபிள் ஒன்றை இயக்கக்கூடியதாக மாற்றுவதற்கு கோப்புகள் வகுப்பில் உள்ளது :

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