如何将Java泛型从方法应用到同一类中的字段 - java

我有一个函数,该函数提供带有给定注释的类的映射

void <A extends Annotation> ImmutableMap<Class<?>, A> find(Class<A> annotation, String packageBase) {
    final ClassLoader loader = Thread.currentThread().getContextClassLoader();

    return ClassPath.from(loader).getTopLevelClassesRecursive(packageBase).stream()
            .filter(x -> x.load().getAnnotation(annotation) != null)
            .collect(Collectors.collectingAndThen(Collectors
                    .toMap(ClassPath.ClassInfo::load, x -> x.load().getAnnotation(annotation)), ImmutableMap::copyOf));
}

我想使通用提供程序具有缓存,如以下示例所示

@Singleton
public class AnnotatedClassProvider {
    private final Map<Class<? extends Annotation>, ImmutableMap<Class<?>, Object>> cache;
    private final String basePackage;

    public AnnotatedClassProvider(String basePackage) {
        this.basePackage = basePackage;
        this.cache = Maps.newHashMap();
    }

    public <A extends Annotation> ImmutableMap<Class<?>, A> get(Class<A> annotation) {
        ImmutableMap<Class<?>, A> cached = cache.get(annotation);
        if (cached != null)
            return cached;

        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        cached = ClassPath.from(loader).getTopLevelClassesRecursive(basePackage).stream()
                .filter(x -> x.load().getAnnotation(annotation) != null)
                .collect(Collectors.collectingAndThen(Collectors
                        .toMap(ClassPath.ClassInfo::load, x -> x.load().getAnnotation(annotation)), ImmutableMap::copyOf));
        this.cache.put(annotation, cached);
        return (cached);
    }
}

我的问题:对于以下地图,我找不到像Object函数中那样用通用A替换get的方法:

private final Map<Class<? extends Annotation>, ImmutableMap<Class<?>, Object>> cache;

编辑:
当我不指定映射泛型时,它将进行编译,但是我必须强制使用get方法。有办法避免这种情况吗?

private final Map<Class<? extends Annotation>, ImmutableMap> cache;

我认为应该看起来像这样

private final <A extends Annotation> Map<Class<A>, ImmutableMap<Class<?>, A>> cache;

参考方案

如果不进行强制转换,这似乎是不可能的,因此以下几行解决了我的问题:

private final Map<Class<? extends Annotation>, ImmutableMap> cache;

public <A extends Annotation> ImmutableMap<Class<?>, A> get(Class<A> annotation) {
    @SuppressWarnings("unchecked")
    ImmutableMap<Class<?>, A> cached = cache.get(annotation);
    ...
}

对于有兴趣的人,这就是我的提供者现在的样子

接口

public interface AnnotatedClassProvider {
    <A extends Annotation> ImmutableMap<Class<?>, A> get(Class<A> annotation) throws IOException;
}

抽象类

public abstract class AbstractAnnotatedClassProvider implements AnnotatedClassProvider {
    private final Map<Class<? extends Annotation>, ImmutableMap> cache;

    public AbstractAnnotatedClassProvider() {
        this.cache = Maps.newHashMap();
    }

    protected final <A extends Annotation> ImmutableMap<Class<?>, A> find(Class<A> annotation, @Nullable String basePackage) throws IOException {
        @SuppressWarnings("unchecked")
        ImmutableMap<Class<?>, A> cached = cache.get(annotation);

        if (cached != null)
            return cached;

        ClassPath classPath = ClassPath.from(Thread.currentThread().getContextClassLoader());

        ImmutableSet<ClassPath.ClassInfo> set = basePackage == null
                ? classPath.getAllClasses()
                : classPath.getTopLevelClasses(basePackage);

        cached = set.stream()
                .filter(x -> x.load().getAnnotation(annotation) != null)
                .collect(Collectors.collectingAndThen(Collectors
                        .toMap(ClassPath.ClassInfo::load, x -> x.load().getAnnotation(annotation)), ImmutableMap::copyOf));
        this.cache.put(annotation, cached);
        return (cached);
    }
}

实作

public final class Providers {
    public static AnnotatedClassProvider newBased(String basePackage) {
        return new AbstractAnnotatedClassProvider() {
            @Override
            public <A extends Annotation> ImmutableMap<Class<?>, A> get(Class<A> annotation) throws IOException {
                return super.find(annotation, basePackage);
            }
        };
    }

    public static AnnotatedClassProvider newSimple() {
        return new AbstractAnnotatedClassProvider() {
            @Override
            public <A extends Annotation> ImmutableMap<Class<?>, A> get(Class<A> annotation) throws IOException {
                return super.find(annotation, null);
            }
        };
    }
}

@Retention(RUNTIME)
@Target(ElementType.TYPE)
public @interface Controller {
    String value();
}

package com.test

@Controller("mainController")
public class Main {

    public static void main(String[] args) {
        AnnotatedClassProvider provider = Providers.newBased("com.test");
        Map<Class<?>, Controller> classes = provider.get(Controller.class);

        classes.forEach((x, y ) -> System.out.println(String.format("Class: %s annotated with %s with value %s",
                x.getName(), y.getClass().getName(), y.value())));
    }
}

输出:Class: Main.java annotated with Controller.class with value mainController

感谢所有评论。

休眠映射<键,设置<值>> - java

我有以下表格:@Entity @Table(name = "events") Event --id --name @Entity @Table(name = "state") State --id --name @Entity @Table(name = "action") Action --id …

无法从ArrayList <String>转换为List <Comparable> - java

当我写下面的代码时,编译器说 无法从ArrayList<String>转换为List<Comparable>private List<Comparable> get(){ return new ArrayList<String>(); } 但是当我用通配符编写返回类型时,代码会编译。private List&l…

合并List <T>和List <Optional <T >> - java

鉴于: List<Integer> integers = new ArrayList<>(Arrays.asList( 10, 12 )); List<Optional<Integer>> optionalIntegers = Arrays.asList( Optional.of(5), Optional.em…

实例化类型<?>的泛型类 - java

我正在为SCJP / OCPJP学习,并且遇到了一个对我来说很奇怪的示例问题。该示例代码实例化了两个通用集合:List<?> list = new ArrayList<?>(); List<? extends Object> list2 = new ArrayList<? extends Object>(); …

List <Dog>是List <Animal>的子类吗?为什么Java泛型不是隐式多态的? - java

我对Java泛型如何处理继承/多态感到困惑。假设以下层次结构-动物(父母)狗-猫(儿童)因此,假设我有一个方法doSomething(List<Animal> animals)。根据继承和多态性的所有规则,我假设List<Dog>是List<Animal>,而List<Cat>是List<Animal&g…