简体   繁体   中英

JAVA Type Parameter in Linked List

Java type parameter declaration as a part of inner class.

The question I have is on linked list. I am seeing the same thing in ArrayList implementation.

public class LinkedList<E> implements Iterable<E> {....

private class LinkedIterator implements Iterator<E>{...} //inner class of LinkedList

private static class ListNode<E> //implemented as nested static class

Question: Why does the iterator (and constructor for LinkedList) both do not require type parameter, I think listNode requires because static class make it can not access class header of the outter class.

Any class definition that is:

  • Inside another class definition.
  • not marked static

is an inner class. Conceptually, the class exists only within a single instance of the outer class. Effectively, it means this:

  • There is a hidden, private, and final field of the outer type. All constructors require an instance of outer, but java syntax is special to pass it: outerRef.new Inner(); - and if you are in a context where Outer.this would be sensible, that is the default value. This field does not have a getter.

  • All type params of the outer class are also available in the inner class unless shadowed.

So, given that private class LinkedIterator is inside class LinkedList , it is this kind of inner class, it has that hidden field, and it inherits the <E> from LinkedList<E> . The Node, however, is static , therefore it does not have that field and does not inherit the <E> - instead choosing to declare it itself.

Note that inner classes are complicated and surprising. They can for example mess up garbage collecting (because they hold a reference to their outer; that will prevent gc of the outer, for example). As a general rule, if you're not sure, strongly prefer static inner classes, making any inheritance of either an instance of outer or its generics explicit.

In other words:

public class Outer<E> {
    public class Inner {}
}

is tricky; don't do that unless you're sure the concept of being an inner class fully applies. If you don't know what that means or aren't sure, write this instead:

public class Outer<E> {
    public static class Inner<E> {
        private final Outer<E> context;

        public Inner(Outer<E> context) {
            this.context = context;
        }
    }
}

omitting all parts you don't need, of course.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM