【问题标题】:Java, Usual interfaces for Generic types - a bad design?Java,通用类型的常用接口 - 一个糟糕的设计?
【发布时间】:2013-03-27 09:27:07
【问题描述】:

我有一个通用接口(我不想使其成为通用接口),带有通用方法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 接口也通用吗?我试图避免手动弄乱 Object 和 casts 并将所有类型的不同属性存储在一个列表中。

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

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);
    }
}

【问题讨论】:

    标签: java generics


    【解决方案1】:

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

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

    如果需要确保容器中每种类型只能放置一个Attribute,只需使用Set即可:

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

    【讨论】:

      【解决方案2】:

      为了在不强制转换的情况下使用接口,您需要将接口设为通用。

      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);
          }
      }
      

      【讨论】:

        【解决方案3】:

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

        似乎最好的解决方案是使您的基类通用。如果你想在一个列表中存储不同类型的属性,那么你就有不同的问题了;您将如何恢复原始类型(无论您是否使用泛型)?

        【讨论】:

        • 将用于一些外部抽象规则的描述。我假设这个属性的用户知道正确的类型,如果他失败了 - 异常是好的
        猜你喜欢
        • 2011-05-09
        • 2020-09-10
        • 1970-01-01
        • 2013-02-13
        • 1970-01-01
        • 1970-01-01
        • 2019-05-03
        • 1970-01-01
        • 2013-02-15
        相关资源
        最近更新 更多