java如何将对象类型的实例“动态”转换为其特定的数据类型?
public Object foo(int opt){
if (opt == 0) return new String();
else if (opt == 1) return new Integer(1);
else if (opt == 2) return new Double(1);
else if ...
.. and many more
}
public void doSomething(String s){..}
public void doSomething(Integer i){..}
public void doSomething(Double d){..}
... and many more doSomething method
public static void main(String[] args){
...
Object o = foo(x); //x is a value obtained during runtime, e.g. from user input
//now I want to call doSomething method
// (1)
if (o instanceof String) doSomething((String) o);
else if (o instanceof Integer) doSomething((Integer) o);
else if (o instanceof Double) doSomething((Double) o);
...
// (2)
}
有没有更好的方法来简化(1)中包含的语句。。。(2)?
Java反射有用吗
# 1 楼答案
在Java中这样做没有任何意义。Java是静态类型的,如果要动态转换它,必须有一个switch语句才能这样做,以便在不同的对象上调用不同的方法
例如——如果您有一个字符串或int,并且希望“动态”强制转换它(不带开关),那么您可以对这两个字符串或int执行什么不需要不同代码的操作
我想我是说,如果你必须强制转换,因为你想访问两个对象不同的东西(一个不同的方法),那么你怎么能在没有开关的情况下访问这个不同的方法呢
一个例外可能是内在变量——对于那些想要泛型的人来说,但是在类之外使用内在变量是个坏主意
哦,你可能真正想要的是让所有的类实现同一个接口——然后你就不用强制转换了
铸造应该是非常罕见的
# 2 楼答案
高效、干净地处理此问题的最佳方法是让foo为对象返回holder类
# 3 楼答案
基本上,您希望在执行时执行重载解析—您不可能简单地做到这一点
在一些情况下,visitor pattern可以帮助,但我认为在这里不会。我想你被困在或者这里的代码,或者反射。我从来没有像我的一些同事那样热衷于访客模式——它总是感觉有点凌乱——但值得一想
你能让
foo
调用正确的doSomething
重载而不是仅仅返回值吗?这是一段知道正在构造什么的代码——如果您可以通过适当的重载向它传递一个对象来调用doSomething
,那么您将在一个地方得到特定于类型的逻辑在Java 7中,InvokedDynamic可能在这种情况下很有用——当然C#4中的
dynamic
类型会有所帮助——但我还没有对InvokedDynamic进行足够的研究来确定这一点# 4 楼答案
这里的问题可能是关注点分离。Java是一种面向对象的语言,它可能有助于尝试以面向对象的方式解决问题。在这种情况下,您可能会问为什么main应该关心o是什么类型的对象。相反,您可能会考虑使用一组类,每个类都知道如何以自己的方式做一些事情。p>
您的foo()方法实际上变成了一个工厂,从那时起,您不再需要关心foo返回了什么样的东西
# 5 楼答案
Java反射有些帮助,但缺少一段数据。此外,反射通常会抛出许多需要捕获的已检查异常。(我在代码后面加了一个列表)
持有“doSomething”方法的对象是什么?在本例中,我使用变量名“someObject”来表示持有“doSomething”方法的对象。你需要用这个来代替更感性的东西
另外,只是一个警告,这不会捕获派生类型,因此如果方法定义与给定的类型不匹配,您将得到一个MethodNotFound异常
警告:以这种方式使用反射时,您需要处理以下异常:(这不是一个不寻常的列表,顺便说一句,反射在异常方面通常非常嘈杂)