难以理解Java中的泛型方法

时间:2013-10-08 10:36:04

标签: java generics

我正在尝试用Java编写一个具有混合返回类型的方法(就像你在PHP中一样)。

此方法假定使用简单的用户输入字符串,并使用泛型将其转换为适当的类型并返回该值。

@SuppressWarnings("unchecked")
public static <T> T askUser(String message, Class clazz) throws NumberFormatException {
    // get the user input
    String inputString = JOptionPane.showInputDialog(message),
            className = clazz.getCanonicalName();
    // return a Boolean, Integer or String
    if (className.equals(Boolean.class.getCanonicalName())) {
        return (T) Boolean.valueOf(inputString);
    } else if (className.equals(Integer.class.getCanonicalName())) {
        return (T) Integer.valueOf(inputString);
    } else /*return the String*/ {
        return (T) inputString;
    }
}

我正在运行这样的代码:

    String userName = name_game.<String>askUser("Please enter your name.", String.class);
    Integer userAge = name_game.<Integer>askUser("Please enter your age.", Integer.class);
    tellUser("So your name is %s and your age is %d...", userName, userAge);
    Boolean confirm = name_game.<Boolean>askUser("Is this correct?", Boolean.class);
    tellUser("You said %b.", confirm);

但我无法弄清楚如何在没有(T)强制转换的情况下使其工作,并且传递Class参数似乎也可以避免。

如何编写此方法而不必求助于转换为(T)?

3 个答案:

答案 0 :(得分:3)

public static <T> T askUser(String message, Class<T> clazz) throws NumberFormatException {
    // ...
}

使用此声明也可以避免方法调用前的内部强制转换和泛型。

答案 1 :(得分:2)

泛型不能让你:

  

使用简单的用户输入字符串   泛型,将其转换为适当的类型并返回该值。

例如:如果有人提出File并希望将其转换为Dog该怎么办?

您可以创建一个带有CreatableFromString签名的接口createFromString( String userData),使用给定的String实例化正确的对象。

然后,您具有完全类型安全性,甚至不使用泛型 - 并且您不必担心File<->Dog情况,因为只有实现CreatableFromString的类才能放入askUser参数。< / p>

这个解决方案的缺点是askForUser将返回CreatableFromString,但你可以使这个通用:

Dog dog = name_game.createByUserAskDialog( "Please enter dog name.", Dog.class );

public static <T extends CreatableFromString> T askUser(String dialogTitle , Class<T> clazz) {
    ...get "data" from user...
    return T.createFromString( data ) ;
}

如果要将用户字符串转换为现有类型,则不能将Class<T>作为参数传递给您的工厂:

public interface CreatableFromStringFactory<T> {
  public T createFromString( String s );
}

...

public class BooleanFromStringFactory implements CreatableFromStringFactory<Boolean> {
  public Boolean createFromString( String s ) {
    if ( s.equals( "yes" ) ) {
      return Boolean.TRUE;
    }
    return Boolean.FALSE; 
  }
}

...
booleanFromStringFactory  = new BooleanFromStringFactory();
...
Boolean c = name_game.askUser("Is this correct?",booleanFromStringFactory );

答案 2 :(得分:1)

我认为最好编写一些代码将字符串转换为适当的数据类型,并使用不同的方法来获取用户的年龄,姓名等。