java - 如何使用泛型调用带有类参数的方法?

标签 java generics

我有一个类,它使用反射来操作其他类:

package com.cw.cmt;

public class Container<T extends Class<?>> {
    private final Class<T> clazz;

    public Container(final Class<T> clazz) {
        this.clazz = clazz;
        System.out.println("Expensive constructor for " + this);
    }

    @Override
    public String toString() {
        return String.format("Container [clazz=%s]", clazz);
    }
}

因为构建这些可能会很昂贵,所以我想将它们缓存在 Map 中,以便仅根据需要构建它们:

package com.cw.cmt;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class ContainerCache {
    private static final ConcurrentMap<Class<?>, Container<? extends Class<?>>> cache = new ConcurrentHashMap<>();

    public static <C extends Class<?>> Container<C> getContainer(final Class<C> clazz) {
        final Container<? extends Class<?>> result = cache.computeIfAbsent(clazz, k -> new Container<C>(clazz));
        // it would be nice to eliminate this cast!
        return (Container<C>) result;
    }
}

我无法确定调用此 getContainer 方法的正确通用语法。

// The parameterized method <Class<String>>getContainer(Class<Class<String>>) of type ContainerCache 
// is not applicable for the arguments (Class<String>)
ContainerCache.getContainer(String.class);

// Bound mismatch: The generic method getContainer(Class<C>) of type ContainerCache is not applicable 
// for the arguments (Class<String>). The inferred type String is not a valid substitute for the bounded 
// parameter <C extends Class<?>>
ContainerCache.<String>getContainer(String.class);

// The parameterized method <Class<String>>getContainer(Class<Class<String>>) of type ContainerCache 
// is not applicable for the arguments (Class<String>)
ContainerCache.<Class<String>>getContainer(String.class);

最佳答案

我认为您无法消除转换,因为您的 map 包含多种“类型”的容器,因此您需要转换为正确的容器。 正如所指出的,您的容器应该是 Container<T>以及您的 getContainer 中的更多类型转换应该做你想做的事:

public static class ContainerCache {
  private static final Map<Class<?>, Container<?>> cache = new ConcurrentHashMap<>();

  public static <T> Container<T> getContainer(final Class<T> clazz) {
    return (Container<T>) cache.computeIfAbsent(clazz, c -> new Container<> ((Class<T>) c));
  }
}

public static class Container<T> {
  private final Class<T> clazz;

  public Container(final Class<T> clazz) {
    this.clazz = clazz;
    System.out.println("Expensive constructor for " + this);
  }

  @Override
  public String toString() {
    return String.format("Container [clazz=%s]", clazz);
  }
}

这有点难看,但我认为你不能做得更好......

关于java - 如何使用泛型调用带有类参数的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29801068/

相关文章:

java - 允许单位使用设计模式在 Java 中攻击地面、空中或两者的能力的接口(interface)

java - 尝试空捕获

java - T 扩展 SomeClass 的意义何在?

Java 泛型 - 类<接口(interface)>

Java Eclipse : Is it possible to pass arguments between different projects?

java - SAP DBTech JDBC : Cannot connect to jdbc:sap://192. 168.33.114:39015/[SAP DBTech JDBC: [2]: 一般错误: SYSTEMDB 未连接]

c# - 泛型 - 其中 T 是一个数字?

generics - Kotlin类型参数的子类

java - 允许使用 Java 中的泛型将子类添加到列表中

java - 如何使用 Java API Streams 执行此类操作?