为什么这个泛型java方法接受两个不同类型的对象?

时间:2012-12-18 21:22:51

标签: java generics methods parameters

此方法应采用两个相同类型的对象并随机返回其中一个对象:

public static <T> T random(T o1, T o2)
{
   return Math.random() < 0.5 ? o1 : o2;
}

现在,为什么编译器接受具有不同类型的两个参数?

random("string1", new Integer(10)); // Compiles without errors

修改 现在我知道这两个参数都被隐式上升了,我想知道为什么编译器时会调用以下方法:

public static <T> List<T> randomList(List<T> l1, List<T> l2) {
        return Math.random() < 0.5 ? l1 : l2;
    }

呼叫:

randomList(new ArrayList<String>(), new ArrayList<Integer>()); // Does not Compile

如果那些ArrayList参数也被上传到Object,为什么这次会给我一个错误?

4 个答案:

答案 0 :(得分:9)

T被推断为Object,两个参数都被隐式上传。

因此代码相当于:

Main.<Object>random((Object)"string1", (Object)new Integer(10));

更令人惊讶的是,以下编译:

random("string1", 10);

第二个参数是自动装入Integer,然后两个参数都被上传到Object

答案 1 :(得分:5)

T被推断为StringInteger的常见超类型,

Object & Serializable & Comparable<? extends Object & Serializable & Comparable<? extends ... ...
好吧,没有人需要关心它。

您可以在参数类型上添加更多约束

public static <T1,T2 extends T1> T1 random(T1 o1, T2 o2)

在列表示例中,您需要使用通配符来获得类似的效果

public static <T> List<? extends T> randomList(
                                    List<? extends T> l1, List<? extends T> l2)

答案 2 :(得分:2)

  

知道我知道两个参数都被隐式升级,   我想知道为什么编译器在调用以下内容时会抱怨   方法:

因为即使A是[{1}}的子类型,如果A和B不同,B也不是List<A>的子类型。

答案 3 :(得分:1)

因为您没有以安全,通用的方式调用它。尝试

MyClass.<String>random("string1", new Integer(10));

你会收到编译错误。

或者让编译器推断出类型,你也应该得到一个编译错误:

String s = random("string1", new Integer(10));