Java 方法返回给定接口的实现

Java 方法返回给定接口的实现,java,generics,Java,Generics,以代码为例: /** * For a given interface, return a default implementation */ public class ImplementationFactory<T> { public static void main(String[] args) { AddressBookUI ui = ImplementationFactory.getImpl(AddressBookUI.class); } publ

以代码为例:

/**
 * For a given interface, return a default implementation
 */
public class ImplementationFactory<T>
{
  public static void main(String[] args)
  {
    AddressBookUI ui = ImplementationFactory.getImpl(AddressBookUI.class);
  }

  public static <T extends BasicUI> T getImpl(Class<T> uiClass)
  {
    if (uiClass.equals(AddressBookUI.class))
    {
      /*
       * Compile error if cast is removed.
       * Casting to T leaves an unchecked cast warning.
       */
      return (T) new AddressBookFrame();
    }

    // a bunch more else-if checks would be here

    return null;
  }
}

// These are defined elsewhere:
interface BasicUI {}
interface AddressBookUI extends BasicUI {}
interface StockQuoteUI extends BasicUI {}

class AddressBookFrame implements AddressBookUI {}
class StockQuoteFrame implements StockQuoteUI {}
/**
*对于给定接口,返回默认实现
*/
公共类实现工厂
{
公共静态void main(字符串[]args)
{
AddressBookUI=ImplementationFactory.getImpl(AddressBookUI.class);
}
公共静态T getImpl(类uiClass)
{
if(uiClass.equals(AddressBookUI.class))
{
/*
*如果删除强制转换,则编译错误。
*强制转换为T会留下未经检查的强制转换警告。
*/
返回(T)新的AddressBookFrame();
}
//如果支票在这里的话,还有很多
返回null;
}
}
//这些定义在其他地方:
接口{}
接口AddressBookUI扩展BasicUI{}
接口StockQuoteUI扩展BasicUI{}
类AddressBookFrame实现AddressBookUI{}
类StockQuoteName实现StockQuoteUI{}
为什么一开始就需要getImpl()中的强制转换?有没有更好的办法

此外,我还尝试创建一个映射,而不是在getImpl()中使用chained if else检查,如下所示:

private static Map<Class<? extends BasicUI>, Class<? extends BasicUI>> map;

private static Map需要强制转换,因为在编译时,无法判断
AddressBookFrame
是否是
T
的实例

要避免警告,请在运行时检查类型:

return uiClass.cast(new AddressBookFrame());

这样做,您的映射实现就可以工作并且是类型安全的。

需要强制转换,因为在编译时,无法判断
AddressBookFrame
是否是
T
的实例

要避免警告,请在运行时检查类型:

return uiClass.cast(new AddressBookFrame());

这样做,您的map实现就可以工作并且是类型安全的。

“因为在编译时,没有办法判断…”我想这就是我困惑的症结所在。有什么不可以?对于给定的提供类型(AddressBookUI),它应该知道返回类(AddressBookFrame)是否属于该类型。作为程序员,您知道这一点,因为您进行了
.equals()
检查。编译器没有那么聪明。对给定参数进行了.equals()检查(基本上是映射的长形式替代)。有问题的强制转换是在返回的实例上进行的。“这样做,您的映射实现将工作并且是类型安全的”。也许我在我的OP中不清楚,但没有。请看我为添加另一种类型和BasicUI实现所做的编辑。我不想说“map.put(AddressBookUI.class,StockQuoteFrame.class);”(不匹配)好的,然后在创建映射后添加一个检查,如果任何映射都不正确,它会引发异常。“因为,在编译时,没有办法判断…”我想这是我困惑的症结所在。有什么不可以?对于给定的提供类型(AddressBookUI),它应该知道返回类(AddressBookFrame)是否属于该类型。作为程序员,您知道这一点,因为您进行了
.equals()
检查。编译器没有那么聪明。对给定参数进行了.equals()检查(基本上是映射的长形式替代)。有问题的强制转换是在返回的实例上进行的。“这样做,您的映射实现将工作并且是类型安全的”。也许我在我的OP中不清楚,但没有。请看我为添加另一种类型和BasicUI实现所做的编辑。我不想说“map.put(AddressBookUI.class,StockQuoteFrame.class);”(不匹配)好的,然后在创建映射后添加一个检查,如果任何映射都不正确,它会引发异常。