相关疑难解决方法(0)

何时使用通用方法以及何时使用通配符?

我正在阅读OracleDocGenericMethod中的泛型方法.当它说何时使用通配符以及何时使用通用方法时,我对比较感到非常困惑.引用文件.

interface Collection<E> {
    public boolean containsAll(Collection<?> c);
    public boolean addAll(Collection<? extends E> c);
}
Run Code Online (Sandbox Code Playgroud)

我们可以在这里使用泛型方法:

interface Collection<E> {
    public <T> boolean containsAll(Collection<T> c);
    public <T extends E> boolean addAll(Collection<T> c);
    // Hey, type variables can have bounds too!
}
Run Code Online (Sandbox Code Playgroud)

[...]这告诉我们类型参数被用于多态; 它唯一的作用是允许在不同的调用站点使用各种实际的参数类型.如果是这种情况,则应使用通配符.通配符旨在支持灵活的子类型,这是我们在此尝试表达的内容.

难道我们不认为外卡(Collection<? extends E> c);也支持那种多态?那为什么泛型方法的使用被认为不好呢?

继续向前,它说,

通用方法允许使用类型参数来表示方法和/或其返回类型的一个或多个参数的类型之间的依赖关系.如果没有这种依赖关系,则不应使用通用方法.

这是什么意思?

他们提出了这个例子

class Collections {
    public static <T> void copy(List<T> dest, List<? extends T> src) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

[...]

我们可以用另一种方式为这种方法编写签名,而不使用通配符:

class Collections {
    public static <T, S extends …
Run Code Online (Sandbox Code Playgroud)

java generics wildcard

115
推荐指数
3
解决办法
5万
查看次数

泛型和ReadObject

我有一个使用泛型和对象序列化的简单服务器.(T是输入格式,U是输出格式).仅处理输入的简化版本如下所示:

public class Server <T, U> implements Runnable {

    @override
    public void run () {

    try (ObjectInputStream inReader = new ObjectInputStream (this.connection.getInputStream ())) {
        T   lastObj;
        while (true) {
            lastObj = (T) inReader.readObject ();
            System.out.println (lastObj.getClass ().getName ());
            if (null != lastObj) {
                this.acceptMessage (lastObj);
            }
        } catch (IOException | ClassNotFoundException ex) {
            Logger.getLogger (this.getClass ().getName ()).log (Level.SEVERE, ex.getMessage (), ex);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我启动服务器

Server <Integer, String> thisServer = new Server ();
Run Code Online (Sandbox Code Playgroud)

那么我希望它只接受Integer对象并返回Strings作为输出.

但是,我使用的是从System.in读取的简单客户端,用于测试和发送字符串到服务器.令我惊讶的是,服务器接受了输入.只是为了确保它真的接受了一个非TI类型的对象,添加了一行来回显出最后一个对象是什么类.

System.out.println (lastObj.getClass ().getName ());
Run Code Online (Sandbox Code Playgroud)

这确实输出了Java.lang.String. …

java generics serialization network-programming

2
推荐指数
1
解决办法
2084
查看次数