Java 计算T.class而不通过一个类<;T>;参数

Java 计算T.class而不通过一个类<;T>;参数,java,generics,Java,Generics,我正在开发一个类,它的功能类似于JTable的方法。我希望有类特定的格式化程序,将对象转换为适合显示的字符串 public interface Formatter<T> { String format(T value); } private Map<Class<?>, Formatter<?>> formatters; public <T> void addFormatter(Formatter<T> forma

我正在开发一个类,它的功能类似于JTable的方法。我希望有
特定的格式化程序,将对象转换为适合显示的字符串

public interface Formatter<T> {
    String format(T value);
}

private Map<Class<?>, Formatter<?>> formatters;

public <T> void addFormatter(Formatter<T> formatter) {
    formatters.put(T.class, formatter);
}

有没有一种方法可以在不传递单独的
参数的情况下编写此代码?我尽量避免这样。这似乎是多余的。

不,这是不可能的,因为Java中有泛型。关于泛型类的所有信息在运行时都会丢失,唯一的解决方案是将该类作为参数显式传递。

不,这是不可能的,因为Java中有泛型。有关泛型类的所有信息在运行时丢失,唯一的解决方案是将该类作为参数显式传递。

由于
T.class
在运行时不可用,因此您必须传递单独的参数。一般来说,泛型类型信息在运行时不可用(除非您使用的是无界通配符)。

由于
T.class
在运行时不可用,因此您必须传入单独的参数。一般来说,泛型类型信息在运行时不可用(除非您使用的是无界通配符)。

这在Java语言中是不可能的。所有泛型类型都是在编译时确定的,因此您无法在执行时访问类值。因此,您还需要传递
Class
参数才能访问它

public Class MyGenericClassContainer<T>{

    public T instance;

    public Class<T> clazz;

    public MyGenericClassContainer(Class<T> clazz){
        intance = clazz.newInstance();
    }

}
公共类MyGenericClassContainer{
公共行政实例;
公开课;
公共MyGenericClassContainer(类clazz){
intance=clazz.newInstance();
}
}

这在Java语言中是不可能的。所有泛型类型都是在编译时确定的,因此您无法在执行时访问类值。因此,您还需要传递
Class
参数才能访问它

public Class MyGenericClassContainer<T>{

    public T instance;

    public Class<T> clazz;

    public MyGenericClassContainer(Class<T> clazz){
        intance = clazz.newInstance();
    }

}
公共类MyGenericClassContainer{
公共行政实例;
公开课;
公共MyGenericClassContainer(类clazz){
intance=clazz.newInstance();
}
}

一般来说,这是不可能的。不过,在您的情况下,让
Formatter
实现一个
类getFormatterTargetClass()
方法可能是合理的,然后您可以使用该方法来代替代码中的
T.Class

通常这是不可能的。不过,在您的情况下,让
Formatter
实现一个
类getFormatterTargetClass()
方法可能是合理的,然后您可以使用该方法代替代码中的
T.Class

不是一个解决方案,而是一个黑客

你能做到。但是通过肮脏的手段和反省。以下面的代码为例。礼节:

类参数化测试{
/**
*@将类型参数返回到我们的泛型基类
*/
@抑制警告(“未选中”)
受保护的最终类determinetyparameter(){
Class specificClass=this.getClass();
类型genericSuperclass=specificClass.getGenericSuperclass();
而(!(genericSuperclass instanceof ParameterizedType)&&specificClass!=ParameterizedTest.class){
specificClass=specificClass.getSuperclass();
genericSuperclass=specificClass.getGenericSuperclass();
}
最终参数化类型参数化类型=(参数化类型)genericSuperclass;
最终类型firstTypeParameter=ParameteredType.getActualTypeArguments()[0];
返回(类)firstTypeParameter;
}
}
//将PrMeterizedTest的类型更改为Parameterized或其他类型以显示不同的输出
公共类测试扩展了参数化测试{
公共静态void main(字符串…参数){
测试=新测试();
System.out.println(test.determinitypeparameter());
}
}
在运行时中,您将获得Type参数。因此,在类中,您必须定义一个
class
对象,该对象获取如上所述的类。然后使用
Class.newInstance
获得一个新对象。但是您必须手动处理类型转换等等

问题是:这一切值得吗


我认为没有,因为在泛型类型中使用边界并与绑定类型接口可以避免大多数情况。因此,您应该寻找替代解决方案,而不是解决方案,而是黑客

你能做到。但是通过肮脏的手段和反省。以下面的代码为例。礼节:

类参数化测试{
/**
*@将类型参数返回到我们的泛型基类
*/
@抑制警告(“未选中”)
受保护的最终类determinetyparameter(){
Class specificClass=this.getClass();
类型genericSuperclass=specificClass.getGenericSuperclass();
而(!(genericSuperclass instanceof ParameterizedType)&&specificClass!=ParameterizedTest.class){
specificClass=specificClass.getSuperclass();
genericSuperclass=specificClass.getGenericSuperclass();
}
最终参数化类型参数化类型=(参数化类型)genericSuperclass;
最终类型firstTypeParameter=ParameteredType.getActualTypeArguments()[0];
返回(类)firstTypeParameter;
}
}
//将PrMeterizedTest的类型更改为Parameterized或其他类型以显示不同的输出
公共类测试扩展了参数化测试{
公共静态void main(字符串…参数){
测试=新测试();
System.out.println(test.determinitypeparameter());
}
}
在运行时中,您将获得Type参数。因此,在类中,您必须定义一个
class
对象,该对象获取如上所述的类。然后使用
Class.newInstance
获得一个新对象。但是您必须手动处理类型转换等等

问题是:这一切值得吗


我认为没有,因为在泛型类型中使用边界并与绑定类型接口可以避免大多数情况。因此,你应该寻找替代的解决方案,一个有启发性的练习是问自己,“我该怎么做?”
class ParameterizedTest<T> {

/**
 * @return the type parameter to our generic base class
 */
@SuppressWarnings("unchecked")
protected final Class<T> determineTypeParameter() {
    Class<?> specificClass = this.getClass();
    Type genericSuperclass = specificClass.getGenericSuperclass();
    while (!(genericSuperclass instanceof ParameterizedType) && specificClass != ParameterizedTest.class) {
        specificClass = specificClass.getSuperclass();
        genericSuperclass = specificClass.getGenericSuperclass();
    }
    final ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;

    final Type firstTypeParameter = parameterizedType.getActualTypeArguments()[0];
    return (Class<T>) firstTypeParameter;
}



}

//change the type of PrameterizedTest<Integer> to Parameterized<String> or something to    display different output
public class Test extends ParameterizedTest<Integer>{
 public static void main(String... args){
    Test test = new Test();
    System.out.println(test.determineTypeParameter());
}
}
public interface Formatter {
    String format(Object value);
}

private Map formatters;

public void addFormatter(Formatter formatter) {
    formatters.put(?, formatter);
}