Java泛型理解类型

时间:2017-06-05 09:39:45

标签: java generics

我正在从https://docs.oracle.com/javase/tutorial/java/generics/bounded.html学习Java泛型,我对下面的代码示例有些怀疑:

public class Box<T> {

    private T t;          

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

    public <U extends Number> void inspect(U u) {
        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }

    public static void main(String[] args) {
        Box<Integer> integerBox = new Box<Integer>();
        integerBox.set(new Integer(10));
        integerBox.inspect("some text"); // error: this is still String!
    }
}

为什么没有像下面所示的那样编写的inspect()方法呢?

 public <T extends Number> void inspect(T t) { }

还有一些其他代码示例具有以下语法。第一对代表什么?

public <K,V> SomeClass<K,V>

静态代表什么?

public static <T> int countGreaterThan(T[] anArray, T elem)

3 个答案:

答案 0 :(得分:2)

方法Box.inspect()需要一个扩展Number的类型,因此当参数为String时它不适用。

Box.inspect()只是应用于方法的泛型类型的示例。

另一方面,您有一个类Box,其类型为T,但您也可以使用另一种类型U的方法,该方法比{{更宽泛(上限)T 1}}。

该类本身并未说明如何使用inspect以及为什么,它只是为您提供处理不同类型的可能性。不要对这个样本寄予厚望。

考虑一下它只是一个解释如何使用泛型(不是很好的逻辑)的样本。

关于public class SomeClass<K,V>声明,这是一个包含多个泛型类型的声明。

this是此案例的真实示例,K是键值的类型,V是值的类型。

答案 1 :(得分:0)

public <U extends Number> void inspect(U u) {

等待Number类型的参数或派生它的参数 所以你当然不能传递一个String值:

integerBox.inspect("some text"); // error: this is still String!

在您的课程中,您声明了两个参数化类型:

  • 课堂宣言中的一个:public class Box<T> {

  • public <U extends Number> void inspect(U u)方法中的另一个。

这些设定了两个不同的约束。

当您将具有整数的Box实例声明为泛型类型时:

Box<Integer> integerBox = new Box<>(); 

使用T类型的以下字段将与整数类型相关联:

private T t;          

public <U extends Number> void inspect(U u)方法不使用T. 类型。
所以你可以在两种情况下使用不同的类型:

    Box<Integer> integerBox = new Box<Integer>();
    integerBox.set(new Integer(10));
    integerBox.inspect(Float.valueOf(10)); // I pass a float and it is valid.

如果您以这种方式声明方法:

 public <T extends Number> void inspect(T t) { }

您在声明的方法中与T具有相同的行为,而在类中声明的是另一个T类型。
但是这种方式具有误导性,因为您使用两次相同的类型名称(T),而这些是不同的类型。

否则,要将方法的参数约束为类中声明的类型,您还不必声明类型。

这就够了:

 public void inspect(T t) { }

现在你只能在两种情况下使用相同的类型:

    Box<Integer> integerBox = new Box<Integer>();
    integerBox.set(new Integer(10));
    integerBox.inspect(Float.valueOf(10)); // doesn't compile

答案 2 :(得分:-1)

是。 Freedev的回答是正确的。 尝试

public static void main(String[] args) {
    Test1<Integer> integerBox = new Test1<Integer>();
    integerBox.set(new Integer(10));
    integerBox.inspect(78); //  inspect method expect a interger value
}