gpt4 book ai didi

java - 我是否破坏了 Java 的局部变量类型推断?

转载 作者:行者123 更新时间:2023-11-30 01:57:56 25 4
gpt4 key购买 nike

我写了一个方法来“典型”String ,并尝试推断其中保存的数据类型。 (this gist 的稍微修改版本)。该方法返回推断的 Class和原来的String (可能稍作修改——修剪周围的空白等)在 Map.Entry<Class, String> 中。例如,typify("3f")返回<Float, "3.0"> , typify(" c ")返回<Character, "c">等等。

我的下一步是编写第二个方法来“解码”这些返回的 Map.Entry对象,因此可以将它们直接分配给推断类型的对象。例如:

Float f = decodeTypify(typify("3.14f"))
Boolean b = decodeTypify(typify("false"))

...等等。这段代码如下:

  @SuppressWarnings("unchecked")
public static <T> T decodeTypify (Entry<Class, String> entry) {

// String
if (entry.getKey() == String.class)
return (T) entry.getValue();

// Boolean
else if (entry.getKey() == Boolean.class)
return (T) (Boolean) Boolean.parseBoolean(entry.getValue());

// Byte
else if (entry.getKey() == Byte.class)
return (T) (Byte) Byte.parseByte(entry.getValue());

// Character
else if (entry.getKey() == Character.class)
return (T) (Character) entry.getValue().charAt(0);

// Short
else if (entry.getKey() == Short.class)
return (T) (Short) Short.parseShort(entry.getValue());

// Integer
else if (entry.getKey() == Integer.class)
return (T) (Integer) Integer.parseInt(entry.getValue());

// Long
else if (entry.getKey() == Long.class)
return (T) (Long) Long.parseLong(entry.getValue());

// Float
else if (entry.getKey() == Float.class)
return (T) (Float) Float.parseFloat(entry.getValue());

// Double
else if (entry.getKey() == Double.class)
return (T) (Double) Double.parseDouble(entry.getValue());

// LocalDateTime
else if (entry.getKey() == LocalDateTime.class)
return (T) (LocalDateTime) stringAsDate(entry.getValue());

else return null;
}

这似乎很有效,尤其是与 Java 的新局部变量类型推断结合使用时:

var f = decodeTypify(typify("literally anything"))

现在我根本不需要关心返回的类型,因为 Java 会负责给出 f正确的类型。但请注意,如果 entry decodeTypify() 的参数有一个与大 if-else 中的任何选项都不匹配的 key 树,然后decodeTypify()返回null 。这是使用 Java 11.0.1 在 jshell 中运行的此方法:

jshell> var x = decodeTypify(typify(null))
x ==> null

我分配了一个 null本地类型推断变量的值!这个isn't supposed to be possible 。这个的副作用(看起来)是我实际上可以告诉 x具有任何类型,没有警告:

jshell> Object x = decodeTypify(typify(null))
x ==> null

jshell> String x = decodeTypify(typify(null))
x ==> null

jshell> Byte x = decodeTypify(typify(null))
x ==> null

请注意,非 null 的情况并非如此。返回:

jshell> var x = decodeTypify(typify("3"))
x ==> 3.0

jshell> Boolean x = decodeTypify(typify("3"))
| Exception java.lang.ClassCastException: class java.lang.Double cannot be cast to class java.lang.Boolean (java.lang.Double and java.lang.Boolean are in module java.base of loader 'bootstrap')
| at (#21:1)

我破坏了什么吗?如果没有,有人可以解释一下这里发生了什么吗?

最佳答案

你没有破坏任何东西。您不能直接分配 null,但通过方法调用间接分配它是完全可以的。

这样做的原因是,通过仅分配null,编译器没有信息来知道您想要什么类型。可以做出的唯一推论是针对可用的最通用类型,Object,如果这是正确的推论,那么只需将其显式声明即可!多了 3 个字符。

当编译器有一个方法调用需要使用时,它可以使用该方法的返回类型来进行类型推断。

public static String foo() {
return null;
}

public static <T> T bar() {
return null;
}

public static <T> T baz(Class<T> clazz) {
return null;
}

public static void main(String[] args) {
var a = null; // compile error
var b = foo(); // fine
var c = bar(); // fine
var d = baz(String.class); //fine
}

关于java - 我是否破坏了 Java 的局部变量类型推断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53746305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com