Java IntelliJ在流中看到对象,而不是正确的类类型
我在反射、Java8流和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
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问题?我附加了完整的类。我还按照建议替换了流。问题在于可选文件中的原始类型。你能解释一下为什么它不起作用吗?一旦使用原始类型强制进行未经检查的适用性转换,推断出的签名也会被删除。因此使用对象。之所以这样做,是因为缺少类型参数意味着推理结果不再可以精确依赖。我还按照建议替换了流。问题在于可选文件中的原始类型。你能解释一下为什么它不起作用吗?一旦使用原始类型强制进行未经检查的适用性转换,推断出的签名也会被删除。因此使用对象。之所以这样做,是因为缺少类型参数意味着推理结果不再可以精确依赖。