Java IntelliJ在流中看到对象,而不是正确的类类型

Java IntelliJ在流中看到对象,而不是正确的类类型,java,intellij-idea,java-8,java-stream,Java,Intellij Idea,Java 8,Java Stream,我在反射、Java8流和IntelliJ方面遇到了麻烦 Optional<Class> optionalAnnotationClass=...; // some initialization here Map<Object, Object> anotherMap=new Hashmap(); Class sourceClass = MyClass.class;// some class Arrays.asList(sourceClass.getDeclaredField

我在反射、Java8流和IntelliJ方面遇到了麻烦

Optional<Class> optionalAnnotationClass=...; // some initialization here
Map<Object, Object> anotherMap=new Hashmap();
Class sourceClass = MyClass.class;// some class

Arrays.asList(sourceClass.getDeclaredFields()).stream()
            .filter(field -> (!optionalAnnotationClass.isPresent() || Objects.nonNull(field.getAnnotation(optionalAnnotationClass.get()))))
            .filter(field -> filterFieldClass.length == 0 || Arrays.asList(filterFieldClass).contains(field.getType()))
            .map(field -> doSomething(sourceClass, field))
            .filter(Objects::nonNull)
            .forEach(entry -> anotherMap.put(entry.getKey(), entry.getValue()));
我检查了项目的版本,它的目标是1.8并使用JDK8。我使缓存无效并重新启动IntelliJ

Optional<Class> optionalAnnotationClass=...; // some initialization here
Map<Object, Object> anotherMap=new Hashmap();
Class sourceClass = MyClass.class;// some class

Arrays.asList(sourceClass.getDeclaredFields()).stream()
            .filter(field -> (!optionalAnnotationClass.isPresent() || Objects.nonNull(field.getAnnotation(optionalAnnotationClass.get()))))
            .filter(field -> filterFieldClass.length == 0 || Arrays.asList(filterFieldClass).contains(field.getType()))
            .map(field -> doSomething(sourceClass, field))
            .filter(Objects::nonNull)
            .forEach(entry -> anotherMap.put(entry.getKey(), entry.getValue()));
怎么了

为了完整起见,下面是完整的代码

package com.ladop;

import com.google.common.base.CaseFormat;
import com.google.common.collect.Maps;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkArgument;

public class StaticReflectionUtils {

    public static Map<String, Object> extractStaticField(final Class<?> sourceClass,
                                                         final Optional<Class> optionalAnnotationClass,
                                                         final Class<?>... filterFieldClass) {
        final Map<String, Object> fieldNameToValue = new HashMap<>();
        Arrays.stream(sourceClass.getDeclaredFields())
                .filter(field -> !optionalAnnotationClass.isPresent() || Objects.nonNull(field.getAnnotation(optionalAnnotationClass.get())))
                .filter(field -> filterFieldClass.length == 0 || Arrays.asList(filterFieldClass).contains(field.getType()))
                .map(field -> extractFieldKeyValue(sourceClass, field))
                .filter(Objects::nonNull)
                .forEach(entry -> fieldNameToValue.put(entry.getKey(), entry.getValue()));
        return fieldNameToValue;
    }

    public static Map.Entry<String, Object> extractFieldKeyValue(final Class<?> sourceClass,
                                                                 final Field field) {
        field.setAccessible(true);
        try {
            final String fieldName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, field.getName());
            return Maps.immutableEntry(
                    concatenate(sourceClass.getSimpleName(), fieldName), field.get(null));
        } catch (IllegalAccessException e) {                
        }
        return null;
    }

    protected static String concatenate(final String prefix, final String word) {
        return new StringBuilder()
                .append(prefix)
                .append("_")
                .append(word).toString();
    }

}

出于我不理解的原因,JDK不喜欢第一个过滤器。我通过将表达式包装到方法中对其进行了更改。 发件人:

方法定义为:

private static boolean hasAnnotationIfPresent(final Field field, final Optional<Class> optionalAnnotationClass) {
    return !optionalAnnotationClass.isPresent() || Objects.nonNull(field.getAnnotation(optionalAnnotationClass.get()));
}

出于我不理解的原因,JDK不喜欢第一个过滤器。我通过将表达式包装到方法中对其进行了更改。 发件人:

方法定义为:

private static boolean hasAnnotationIfPresent(final Field field, final Optional<Class> optionalAnnotationClass) {
    return !optionalAnnotationClass.isPresent() || Objects.nonNull(field.getAnnotation(optionalAnnotationClass.get()));
}
首先,将Hashmap更改为Hashmap,然后。。。对于可编译代码,可将其设置为可选的.empty

其次,您的示例缺少一些声明,因此我添加了以下内容用于测试:

private static class MyClass {}
private static Class<?>[] filterFieldClass = {};
private static Map.Entry<Object, Object> doSomething(Class<?> sourceClass, Field field) {
    return null;
}
所有编译错误都消失了!jdk1.8.0_91

因此,如果您的代码没有编译,那么我假设代码中的三个声明类型不同。doSomething很可能采用或返回不同的类型

更新:Eclipse编译正常。使用javac1.8.091编译会产生错误,通过修复原始类型可以消除这些错误,如下所述。 我想Eclipse编译器比Oracle编译器更擅长推断lambda

另一方面,您的代码使用的是原始类型。不要!更改以下内容:

可选源类的可选 另外,Arrays.asList…stream应该是Arrays.stream…

首先,将Hashmap更改为Hashmap,然后。。。对于可编译代码,可将其设置为可选的.empty

其次,您的示例缺少一些声明,因此我添加了以下内容用于测试:

private static class MyClass {}
private static Class<?>[] filterFieldClass = {};
private static Map.Entry<Object, Object> doSomething(Class<?> sourceClass, Field field) {
    return null;
}
所有编译错误都消失了!jdk1.8.0_91

因此,如果您的代码没有编译,那么我假设代码中的三个声明类型不同。doSomething很可能采用或返回不同的类型

更新:Eclipse编译正常。使用javac1.8.091编译会产生错误,通过修复原始类型可以消除这些错误,如下所述。 我想Eclipse编译器比Oracle编译器更擅长推断lambda

另一方面,您的代码使用的是原始类型。不要!更改以下内容:

可选源类的可选
另外,Arrays.asList….stream应该是Arrays.stream….

当您使用与IJ相反的永久构建工具时,它会编译吗?如果不是,代码就错了。也许你是说类是sourceClass的类型?@b这是一个很好的建议。我通过命令行运行mvn clean install,我得到了相同的错误,因此它不是IntelliJ。为什么sourceClass的类型应该很重要?我正在提取字段并对其进行迭代。@b参数已修复,请参见答案,但我无法理解问题所在!JDK问题?当您使用永久性构建工具而不是IJ时,它会编译吗?如果不是,代码就错了。也许你是说类是sourceClass的类型?@b这是一个很好的建议。我通过命令行运行mvn clean install,我得到了相同的错误,因此它不是IntelliJ。为什么sourceClass的类型应该很重要?我正在提取字段并对其进行迭代。@b参数已修复,请参见答案,但我无法理解问题所在!JDK问题?我附加了完整的类。我还按照建议替换了流。问题在于可选文件中的原始类型。你能解释一下为什么它不起作用吗?一旦使用原始类型强制进行未经检查的适用性转换,推断出的签名也会被删除。因此使用对象。之所以这样做,是因为缺少类型参数意味着推理结果不再可以精确依赖。我还按照建议替换了流。问题在于可选文件中的原始类型。你能解释一下为什么它不起作用吗?一旦使用原始类型强制进行未经检查的适用性转换,推断出的签名也会被删除。因此使用对象。之所以这样做,是因为缺少类型参数意味着推理结果不再可以精确依赖。