Java 动态类型方法中的奇数型推理

Java 动态类型方法中的奇数型推理,java,generics,casting,type-inference,Java,Generics,Casting,Type Inference,在处理配置管理器对象时,我希望实现一个方法,从管理器的内部索引中检索一个值,并将其自动转换为所需的类型,从而消除显式转换的需要。我认为这很简单,使用Java在方法头中提供的泛型系统。因此,我将我的方法构建为: public <T> T getSettingAutocast(String key) { T retV = null; try {retV = (T) getSetting(key);}catch (ClassCastExceptio

在处理配置管理器对象时,我希望实现一个方法,从管理器的内部索引中检索一个值,并将其自动转换为所需的类型,从而消除显式转换的需要。我认为这很简单,使用Java在方法头中提供的泛型系统。因此,我将我的方法构建为:

public <T> T getSettingAutocast(String key)
    {
        T retV = null;

        try {retV = (T) getSetting(key);}catch (ClassCastException ignored){}

        return retV;
    }
其中注册表已在该注册表项地址预加载了文件对象

这一切如期而至。然而,如果我把
文件
换成
整数
,事情就不那么顺利了-我得到了一个
类异常
。在调试模式下查看它,
T
是该方法开始时的正确类型,但是当调用cast时,它只是变形为
getSetting
返回的任何类型


我的印象是,编译器试图从目标对象(在本例中为
文件
整数
)推断
,而不是方法体本身中的任何类型。如果有人能提供编译器在处理方法时如何处理类型推断的更多见解,那将不胜感激。

您仍然得到传播的
ClassCastException
的原因是该方法实际上没有强制转换

类型擦除后,赋值为:

retV = (Object) getSetting(key);
当然,这是成功的,因为一切都是一个对象(除非它是基元的,但这样你就不能在这里使用泛型)

演员阵容实际上被推到呼叫站点:

Integer = (Integer) configIO.getSettingAutocast("file");
(尝试反编译代码,您将在那里看到
checkcast
指令)

因此,正如您应该从堆栈跟踪中注意到的那样,这就是引发异常的原因

我的印象是

没有。通过使用此模式,您将得到您应得的。强制转换是告诉编译器信任您的一种方式,因为您知道一些它不知道的类型信息;在这种情况下,您只是在猜测类型,并将其弄错


返回对象,并在调用站点检查类型。是的,它会更丑;但丑陋的代码比美丽但破碎的代码要好。你所铸造的事实应该让你停下来考虑一下这里可能出错的地方,而不是把它隐藏在这个方法里面。

你仍然得到<代码> CasasStasExtExt[/Cuff]的原因是这个方法实际上没有被抛出。

类型擦除后,赋值为:

retV = (Object) getSetting(key);
当然,这是成功的,因为一切都是一个对象(除非它是基元的,但这样你就不能在这里使用泛型)

演员阵容实际上被推到呼叫站点:

Integer = (Integer) configIO.getSettingAutocast("file");
(尝试反编译代码,您将在那里看到
checkcast
指令)

因此,正如您应该从堆栈跟踪中注意到的那样,这就是引发异常的原因

我的印象是

没有。通过使用此模式,您将得到您应得的。强制转换是告诉编译器信任您的一种方式,因为您知道一些它不知道的类型信息;在这种情况下,您只是在猜测类型,并将其弄错


返回对象,并在调用站点检查类型。是的,它会更丑;但丑陋的代码比美丽但破碎的代码要好。事实上,你应该让你停下来停下来考虑一下这里可能出错的地方,而不是把它隐藏在这个方法里面。< / P>没错,这正是我所得到的。然而,我在这里试图完成的是检查方法内部对象类型的某种方法,而不是在方法本身的调用站点进行检查。本质上,我想做的是检查检索到的对象(从
getSetting
返回)是否与目标对象的类型相同,由推断类型变量
T
指定(理论上)。有没有我不知道的另一种方法来实现这一点?还是这个过程只是对这样一个系统要求太多?@Michael,这根本不可能。被调用的方法不获取有关将在其中使用返回值(如果有的话)的上下文的信息。方法的返回类型不是其签名的一部分,因此您甚至不能使用重载来解决它。您所能做的就是使用单独的方法(例如,
getFileSetting
getIntegerSetting
),并在其中调用通用方法/进行转换;或者提供一个
(或类似的)参数,以便您的泛型方法可以检查值是否匹配。我很担心,但这并不是我所期望的。我从一篇摘录中获得了有关类型推断和类型变量转换的信息,例如:“……推断算法确定参数的类型,以及(如果可用)结果被赋值或返回的类型。最后,推断算法尝试找到适用于所有参数的最具体类型。”但是,如果在运行时不知道返回值的用法,那么我想我将不得不求助于手动转换。谢谢你的时间和帮助。对,这正是我得到的。然而,我在这里试图完成的是检查方法内部对象类型的某种方法,而不是在方法本身的调用站点进行检查。本质上,我想做的是检查检索到的对象(从
getSetting
返回)是否与目标对象的类型相同,由推断类型变量
T
指定(理论上)。有没有我不知道的另一种方法来实现这一点?还是这个过程只是对这样一个系统要求太多?@Michael,这根本不可能。被调用的方法不获取有关将在其中使用返回值(如果有的话)的上下文的信息。方法的返回类型不是其签名的一部分,因此您甚至不能使用重载来解决它。你所能做的就是