代码之家  ›  专栏  ›  技术社区  ›  Tushar Pandey

带类型参数的方法和泛型方法类型参数声明的理论区别是什么?

  •  0
  • Tushar Pandey  · 技术社区  · 6 年前

    大家好,我正在学习Java中的泛型。我在其中创建了这个层次结构。 enter image description here

    现在我已经创建了一个 LivingThing

    public class LivingThing<T extends LivingThingTypes> implements Iterable<LivingThingTypes>{
    public ArrayList<T> create(Class<T> type) {
            ArrayList arrayList = new ArrayList<>();
            for (T item : list) {
                if (item.getClass().equals(type)) {
                    arrayList.add(item);
                }
            }
            return arrayList;
        }
    }
    

    所以当我试图进入 create() 类似于此代码段的方法不起作用。

    livingList.create(Human.class).size();
    livingList.create(Cat.class).size();
    livingList.create(Hen.class).size();
    

    但如果我把方法改成这个,它会很好地工作。

    public class LivingThing<T extends LivingThingTypes> implements Iterable<LivingThingTypes>{
            public <V extends LivingThingTypes>ArrayList<V> create(Class<V> type) {
                ArrayList arrayList = new ArrayList<>();
                for (T item : list) {
                    if (item.getClass().equals(type)) {
                        arrayList.add(item);
                    }
                }
                return arrayList;
            }
        }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   YK S    6 年前

    关于泛型,重要的是它们是不变的。这意味着在你的案例中,即使人类的阶级扩展了 LivingThingTypes 但是 List<Human> 不延伸 List<LivingThingTypes> . 所以基本上你不能做以下任务:

    List<Human> list1;
    
    List<LivingThingTypes> list2 = list1; //compile error
    

    这就是泛型的设计方式。原因是想象你有一个动物家长班和狗和猫作为孩子班。现在您创建了一个 List<Dog> 分配给 List<Animal> . 既然动物是猫的父类,你也可以将猫添加到 列出<动物> . 迭代它可能会给出 ClassCastException .现在使用泛型的基本优点是它们提供了类型安全性,但是 类别例外 这意味着情况并非如此,因此泛型是不变的。

    但是当使用扩展和类型参数时,它允许赋值,但是必须记住 PECS(Producer Extends and Consumer Super) .

    在第一种情况下,您有在类级别声明的类型参数。现在,当您创建Livinging类的实例时,必须提到类型参数,例如 LivingThing<LivingThingTypes> livingList = new LivingThing(); . 这就变成了t的值。现在编译器希望您在create方法中发送相同的类型,这也是我在前面的段落中提到的原因。

    在第二种情况下,您将创建一个新的类型参数,该参数仅绑定到方法,这里您将告诉它 V extends LivingThingType 因此现在 Class<V> create方法的类型参数不能接受 Human.class/Hen.class/Cat.class . 您也可以使用相同的类型参数t来代替v,但是为了避免混淆,您应该像以前那样对它们进行不同的命名。

        2
  •  0
  •   Tushar Pandey    6 年前

    因为Java甲骨文文档中定义了这个概念,所以它不起作用。

    enter image description here

    (正如Java文档所说) 给定两个具体的类型A和B(例如,数字和整数),不管A和B是否相关,MyClass与MyClass都没有关系。MyClass和MyClass的公共父级是Object。