When is there need for Some> instead of Some?

后端 未结 4 1307
执笔经年
执笔经年 2020-12-20 15:59

NOTE: This question is not Enum-related, so it\'s not duplicate. Enum\'s are forced to compare only-with-itself because compiler generation of type paramete

4条回答
  •  渐次进展
    2020-12-20 16:22

    Concerning the statement

    every time I've tried to remove additional - no new errors/warnings came up.

    This should not be the case. It should print a warning, because you are using the raw type Some, and the result of this is missing type safety, as demonstrated in the answer by newacct.


    The Dog/Cat example is a bit contrived, and somewhat flawed. You suggested declaring a class

    public class Dog extends Animal { } // Note "Cat" !!!
    

    But here, the type parameter basically means: "This parameter (Cat) is the type that objects of this class (Dog) can be compared with". You are thus explicitly stating that a Dog should be comparable to Cat. Even with sophisticated languages and smart compilers, after all, it's in the responsibility of the programmers to write code that makes sense.


    Indeed, there are not many cases where these self-referential generic types are necessary. One of these examples is sketched in this FAQ entry: It declares a structure of nodes (that is, a tree) where the type parameter can be used to decouple the definition of the tree structure from the actual type of the nodes:

    public class RecurringTest {
        public static void main(String[] args) {
            SpecialNode sa = new SpecialNode(null);
            SpecialNode sb = new SpecialNode(sa);
            SpecialNode s = sa.getChildren().get(0);
        }
    }
    
    abstract class Node> {
        private final List children = new ArrayList();
        private final N parent;
    
        protected Node(N parent) {
            this.parent = parent;
            if (parent != null) {
                this.parent.getChildren().add(getThis());
            }
        }
    
        abstract N getThis();
    
        public N getParent() {
            return parent;
        }
    
        public List getChildren() {
            return children;
        }
    }
    
    class SpecialNode extends Node {
        public SpecialNode(SpecialNode parent) {
            super(parent);
        }
    
        SpecialNode getThis() {
            return this;
        }
    
    }
    

    But from my personal experience, I can say that when you think you need to create such a type, you should thoroughly think about the benefits and drawbacks. The latter mainly refers to reduced readability. When you have the choice between methods like

    Node, T> doSomething(
        Node, ? extends T> p, 
        Node, ? super T> c) { ... }
    

    that are type safe, or methods like

    Node doSomething(Node parent, Node child) { ... }
    

    that are not type safe (because of raw types, or simply because the types have not been genericified), then I'd prefer the latter. Code is read by humans.

提交回复
热议问题