Common wildcards in Java generics

Suppose I have an interface

interface Foo<T> { 
    void foo(T x); 
    T bar() 
}

And this type of object with unknown parameters: foo Buzz Then I can call Baz foo(baz.bar()).

But now I need to add the value Baz Bar () is placed in a collection, and Baz. Above it is called later foo(). It's like

List<???> list; // can I tell the compiler this is the same type as baz's wildcard?
list.add(baz.bar());
...
baz.foo(list.get(1));

This does not work:

List<Object> list;
list.add(baz.bar());
...
baz.foo((???) list.get(1)); // I can't write down the type I need to cast to

Is there any way to do this?

Editor: the above is an oversimplification from my actual situation Say we have

class Bar {
    private final Foo<?> foo;
    private List<???> list; // the type argument can be selected freely

    Bar(Baz baz) {
        foo = baz.getFoo(); // returns Foo<?>,can't be changed 
    }

    void putBar() {
        list.add(foo.bar());
    }

    void callFoo() {
        foo.foo(list.get(0));
    }
}

Solution

This is an awkward question

The solution is to find a scope that contains the use of wildcards, place a type variable on it, replace the wildcard with a reference to the type variable, and then bind the type variable

In your case, it sounds like this class is a necessary scope So:

public class Whatever<T> {
    private List<T> list;
    private Foo<T> baz;

    public void bazToList() {
        list.add(baz.bar());
    }

    public void listToBaz() {
        baz.foo(list.get(1));
    }
}

The problem is that you have added a type variable to the class Now, wherever this class is used, any type that mentions it needs a type binding (so whatever < string > or whatever ) It can be incredible if the code using this class doesn't really care about the type of things it keeps in the list

To solve this problem, you can create a generic holder class It's like:

public class Whatever {
    private WhateverHolder<?> holder;

    public void bazToList() {
        holder.bazToList();
    }

    public void listToBaz() {
        holder.listToBaz();
    }

    private static class WhateverHolder<T> {
        private List<T> list;
        private Foo<T> baz;

        public void bazToList() {
            list.add(baz.bar());
        }

        public void listToBaz() {
            baz.foo(list.get(1));
        }
    }
}

But it's ugly You are introducing a new class and the runtime overhead of a new object just to solve some annoying generics

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>