当前位置: 首页 > 知识库问答 >
问题:

java 8中的类型不匹配错误

越福
2023-03-14

我有以下具有以下方法的类。

public class MyClass {

    public static <T> T getSomeThing(final int id, final java.lang.reflect.Type type, final Map<Integer, String> someThings) {
        final String aThing = someThings.get(id);
        if (aThing == null || aThing.isEmpty()) {
            return null;
        }
        return GsonHelper.GSON.fromJson(aThing, type);
    }

}

GsonHelper为我提供了一些com.google.gson.GsonBuilder

public class GsonHelper {

    public static final com.google.gson.Gson GSON = getGsonBuilder().create();

    public static GsonBuilder getGsonBuilder() {
        return new GsonBuilder().setPrettyPrinting()
                .enableComplexMapKeySerialization()
                .registerTypeAdapter(new com.google.gson.reflect.TypeToken.TypeToken<byte[]>() {
                    // no body
                }.getType(), new Base64TypeAdapter())
                .registerTypeHierarchyAdapter(Date.class, new DateTypeAdapter())
                .registerTypeHierarchyAdapter(Pattern.class, new PatternTypeAdapter())
                .registerTypeAdapterFactory(new ListTypeAdapterFactory())
                .registerTypeAdapterFactory(new MapTypeAdapterFactory())
                .registerTypeAdapterFactory(new SetTypeAdapterFactory());
    }
}

在Java 7之前,我一直使用这种方法,例如:

Map<Integer, String> allThings = new HashMap<>();
//FILL allThings with values

if(MyClass.getSomeThing(7, java.lang.Boolean.class, allThings)){
    //do something
}

这工作得很好。因为这个方法会返回一个布尔值,我可以在“if”中使用它。但是当我换到Java 8时,这就不可能了。编译器抱怨:

类型不匹配:无法从对象转换为布尔值

 //while this is working but would throw a JsonSyntaxException
final String myString = "myInvalidJsonString";
if(GsonHelper.GSON.fromJson(myString, java.lang.Boolean.class)){
    //do something
}

我知道java.lang.Boolean可以为空。我可以通过以下方式解决这个问题:

final Boolean b = MyClass.getSomeThing(7, java.lang.Boolean.class, allThings);
if(b){
    //do something
}

但我很好奇,为什么这在Java 7中有效,而在Java 8中无效。(没有回答)
它们有什么变化?(未回答)
更改为Java 8时出现此编译器错误的原因是什么?(回答)

共有2个答案

田曜瑞
2023-03-14

getSomeThing() 的结果赋值给布尔变量的最后一个版本可以根据 JLS 8 进行推断,因为在赋值上下文中,目标类型布尔值确实允许将 T 推断为布尔值在这里,所有编译器都同意。

关于原始情况,JLS 8没有将if语句的条件归类为赋值上下文。在赋值或调用上下文之外,调用不被视为多边形表达式,而是被视为独立表达式(JLS 15.12第一个项目符号)。独立表达式没有目标类型。在Java8中没有目标类型推断回退到推断TtoObject

Eclipse团队甚至在Java8GA之前就已经要求澄清这方面的问题。不幸的是,最终的问题直到今天仍未解决。

因此:JLS和观察到的< code>javac的行为似乎并不一致。 <罢工> 很可能,JLS才是应该被修复的实体。

更新:JLS不会改变(通过私人邮件确认),因此接受该程序是< code>javac中的一个bug。

编辑:Javac版本12甚至会通过开关表达式传播这个错误:

public class X {
    @SuppressWarnings("preview")
    public void foo(int i) {
        if (switch(i) { default -> magic(); })
            System.out.println("true");
    }
    <T> T magic() { return null; }
}

javac 接受此功能,因为使用目标类型布尔值进行类型推断,但根据 JLS,在此位置执行类型推断是非法的。

丁曦
2023-03-14

您的方法< code >公共静态

if语句不知道< code>T将具有哪种类型,因此不能保证将其转换为布尔值。

为什么不将签名更改为布尔值?

public static boolean getSomeThing(final int id,
                                   final java.lang.reflect.Type t,
                                   final Map<Integer, String> someThings)

还是你在寻找这个?

public static <T> T getSomeThing(final int id,
                                 final Class<T> clazz,
                                 final Map<Integer, String> someThings)

比此代码将编译和工作:

public static void main(String[] args) {
    if (getSomeThing(7, Boolean.class, emptyMap())) {
        System.out.println("It works!");
    }
}

public static <T> T getSomeThing(final int id,
                                 final Class<T> clazz,
                                 final Map<Integer, String> someThings) {
    ...
}
 类似资料:
  • 错误:java.io.ioException:错误值类:类org.apache.hadoop.io.text不是类org.apache.hadoop.mapred.ifile$writer.append(ifile.java:194)在org.apache.hadoop.mapred.task$combineoutputCollector.collect(task.java:1350)在org.a

  • 问题内容: 我试图在Swift中使用JSONDecoder将JSON转换为Structs,所以我编写了所有Structs,将它们修改了几个小时,但它仍然给我这个错误。我不知道是否有办法查看给出此信息的行。我将在下面发布我的struct,并在其后发布Json File链接。 完整的错误描述是: typeMismatch(Swift.Dictionary ,Swift.DecodingError.Co

  • 我正在尝试解析我的json数据 我解析数据的代码是 我得到了错误

  • 我正在使用此代码并获得类型不匹配的错误,运行时错误'13'错误在下面标记的行中,而具体错误是由于其中条件()在查询...

  • 我在这里复制代码;https://developer.android.com/codelabs/kotlin-android-training-view-model#5 但我从DataBindingUtil中得到了一个类型不匹配。充气方法。正在返回ViewDataBinding!,当需要FragmentPlayBinding时。 我https://github.com/google-develop

  • 问题内容: 编写内部API时遇到以下错误。我正在尝试以以下方式读取值(SQL Server 2012): 现在,虽然看起来有些奇怪,但我以这种方式阅读的原因是因为它是我编写的包装程序的一部分,我们使用它来加快sql的读写速度。它接受一个匿名对象,并根据属性名称或属性名称将所有sql值读入其中。 这适用于除以外的所有内容。我进行了类型比较,它也同样失败,因此很hacky,我什至无法检查该列是否为类型