Java,通用类型的常用接口 - 糟糕的设计?

时间:2013-03-27 09:27:08

标签: java generics

我有一个通用的接口(我不想使用泛型)和泛型方法Get以及实现它的泛型类。

@Override没有给我一个警告,代码按预期工作,但我在Foo#Get()中有一个警告: Type safety: The return type T for Get() from the type Test.Foo<T> needs unchecked conversion to conform to TT from the type Test.Attribute

我必须使Attribute接口通用吗?我试图避免手动弄乱对象和强制转换,并将所有类型的不同属性存储在列表中。

(使用static只是在一个文件中编译测试样本 - 它不会改变任何东西)

import java.util.ArrayList;
import java.util.List;

public class Test
{
    static interface Attribute
    {
        <TT> TT Get();
    }

    static class Foo<T> implements Attribute
    {
        T val;

        public Foo(T val)
        {
            this.val = val;
        }

        @Override
        public T Get()
        {
            System.out.println("it is me");

            return val;
        }
    }


    public static void main(String[] args)
    {
        List<Attribute> list = new ArrayList<Attribute>();

        list.add(new Foo<String>("test"));

        String s = list.get(0).Get();

        System.out.println(s);
    }
}

3 个答案:

答案 0 :(得分:1)

为了在不进行投射的情况下使用界面,您需要使界面通用。

import java.util.ArrayList;
import java.util.List;

public class Test
{
    static interface Attribute<E> //Added Generic Param
    {
        <E> E Get();
    }

    static class Foo<T> implements Attribute<T> //Added Generic Param
    {
        T val;

        public Foo(T val)
        {
            this.val = val;
        }

        @Override
        public T Get()
        {
            System.out.println("it is me");

            return val;
        }
    }


    public static void main(String[] args)
    {
        //Specify Type of generic
        List<Attribute<String>> list = new ArrayList<Attribute<String>>(); 

        list.add(new Foo<String>("test"));

        String s = list.get(0).Get();

        System.out.println(s);
    }
}

答案 1 :(得分:1)

基类中泛型方法的问题是有人可以用显式类型参数调用它。这显然在这里毫无意义,这就是编译器抱怨的原因。

似乎最好的解决方案是使您的基类通用。如果要在列表中存储不同类型的属性,则会出现其他问题;你怎么回到原来的类型(无论你是否使用泛型)?

答案 2 :(得分:1)

您可以将Attribute接口设为通用,然后使用wildcard允许任何类型的Attribute放置在List中:

List<Attribute<?>> list = new ArrayList<Attribute<?>>();

如果您需要确保每种类型中只有一个Attribute可以放入容器中,只需使用Set

Set<Attribute<?>> set = new HashSet<Attribute<?>>();