如何使用泛型来调用带有Class参数的方法?

时间:2015-04-22 14:41:29

标签: 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);

1 个答案:

答案 0 :(得分:0)

我认为Container

中存在一些错误
public class Container<T extends Class<?>> {
  private final Class<T> clazz;
}

因此,clazzClass<Class<?>>因为T extends Class<?>

一个简单的修正:

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

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

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

实际上,我没有一个很好的解决方案来避免演员:)