একটি অভ্যন্তরীণ শ্রেণীর উদাহরণ

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 )।

একটি স্ট্যাটিক নেস্টেড ক্লাসের উদাহরণ

পূর্ণসংখ্যা শ্রেণীতে একটি 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 ক্লাসটি পূর্ণসংখ্যা শ্রেণীর অ-স্থির ক্ষেত্র এবং পদ্ধতিগুলি অ্যাক্সেস করে না । উপরন্তু, এটি শুধুমাত্র স্ট্যাটিক valueOf পদ্ধতিতে অ্যাক্সেস করা হয়। অর্থাৎ, এটি পূর্ণসংখ্যা শ্রেণীর সাথেই আবদ্ধ, তার স্বতন্ত্র দৃষ্টান্তের সাথে নয়। এবং এর মানে হল 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;
    	}
    };
}

পদ্ধতিটি একটি খালি ইনপুটস্ট্রিম প্রদান করে , একটি বেনামী ক্লাস দ্বারা বাস্তবায়িত। যেহেতু ক্লাসের বংশধর থাকার কথা নয়, আমরা এটিকে বেনামী করে দিয়েছি।

জাভা স্ট্রীম এপিআই যুক্ত হওয়ার সাথে সাথে, বেনামী ক্লাসগুলি সর্বব্যাপী হয়ে উঠেছে: সমস্ত ল্যাম্বডা এক্সপ্রেশনগুলি বেনামী ক্লাস যা কিছু কার্যকরী ইন্টারফেস বাস্তবায়ন করে। কিছু উদাহরণ বিবেচনা করুন।

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