java static inner class <br />Defining an inner class as a static class is basically the same as defining other classes as static classes, and the reference rules are basically the same. However, the details are still very different. Specifically, there are mainly the following areas to attract the attention of all program developers.
(1) Generally speaking, if an inner class is not defined as a static inner class, then it cannot be defined as a static member variable and a static member method when defining member variables or member methods. That is, static members cannot be declared in non-static inner classes.
(II) Generally, non-static external classes can access member variables and methods of their external classes at will (including methods declared as private). However, if an inner class is declared static, it will have many external classes including its own. limitations. A static inner class cannot access non-static member variables and methods of its external class.
(3) When creating a non-static member internal class in a class, there is a mandatory provision, that is, instances of internal classes must be bound to instances of external classes. Then you need to define a static inner class in an external class, and you do not need to use the keyword new to create an instance of the inner class. That is, when creating an internal object of a static class, objects of its external class are not needed.
Java uses the following internal class when implementing LinkedList:
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { ............ private static class En try<E> { E element; Entry <E> next; Entry<E> previous; Entry(E element, Entry<E> next, Entry<E> previous) { this.element = element; this.next = next; this.previous = previous ous; } } private Entry<E> addBefore(E e, Entry<E> entry) { Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); newEntry.previous.next = newEntry; newEn try.next.previous = newEntry; size++; modCount++; return newEntry; } ...... }
Here is the typical usage of static inner classes
Java synchronization tool class
/** * Multiple threads need to be started to import interface data into the target in batches. It is required that * Each time you execute, you must ensure that the previous task has ended. There are many ways to deal with this requirement, which is the essence of the problem of * inter-thread synchronization. Just in the past two days, I have also been paying attention to thread synchronization related things. jdk provides a lot of thread* synchronization tool classes. CountDownLatch: a synchronization auxiliary class that allows it to be completed before completing a set of * operations being executed in other threads. One or more threads are waiting. * Initialize CountDownLatch with the given count. Since the countDown() method is called, the * await method will be blocked until the current count reaches zero. After that, all waiting threads will be released and all subsequent calls to await will be returned immediately. * This phenomenon only occurs once - the count cannot be reset (this is very important). If you need to reset the count, consider using CyclicBarrier. * The following is a simple example to simulate this requirement. Of course, there may be some unreasonable aspects in order to simulate the scene. Here we mainly explain * CountDownLatch synchronization. The source code of CountDownLatch will be analyzed later, which mainly involves AbstractQueuedSynchronizer * Class, its class content is relatively complex* **/ import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; pub lic class Driver { static List< Integer> strList = null; int k = 0; static { //Simulated data strList = new ArrayList<Integer>(); for (int i = 0; i < 50; i++) { strList.add(i); } } public static void main(String args[]) { boolean isEnd = true; //In order to verify the correctness, only 20 times int count=0; Driver d = new Driver(); while (isEnd && strList.size() > : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 0&&count<20) { CountDownLatch startSignal = new CountDownLatch(1); final CountDownLatch doneSignal = new CountDownLatch(5); for (int i = 0; i < 5 ; ++i) { new Thread(d.new Worker(startSignal, doneSignal,i)).start(); } //Count minus 1 child thread Worker can execute startSignal.countDown(); try { new Thread(new Runnable() { Random r = new Random(); @Override publ ic void run () { try { //The main thread blocks know that all child threads clear doneSignal doneSignal.await(); } catch (InterruptedException e) { e.printStackTrace(); } while(strList.size()<= 0){ int pos = r.nextInt(1000); strList.clear(); for (int i = pos; i < pos + 50; i++) { strList.add(i); } } } } }).start(); isEnd = true; } catch (Exception e) { e.printStackTrace(); } count++; } } class Worker implements Runnable { private final CountDownLatch startSignal; p rivate final CountDownLatch doneSignal; private int i; Worker(CountDownLatch startSignal, CountDownLatch doneSignal, int i ) { this.startSignal = startSignal; this.doneSignal = doneSignal; this.i=i; } public void run() { try { // Wait for the main thread to execute countDown startSignal.aw ait(); doWork(); //Count down 1 doneSignal.countDown(); } catch (InterruptedException ex) { } // return; } void doWork() { synchronized (strList) { int start=(i)*(50/5); int end=(i+1 )*(50/5); for (int i = start; i < end; i++) { System.out.println(strList.get(i) + "---" + "Deleted"); } } } } }