有没有办法避免Java';s awkard对象强制转换语法?
例如,我有一个有没有办法避免Java';s awkard对象强制转换语法?,java,syntax,casting,Java,Syntax,Casting,例如,我有一个对象“假装”为字符串: Object o = new String("dsadsa"); 如果要使用该对象的字符串函数,首先必须将其转换为如下字符串: ((String)o).indexOf("sad"); 当有这么多括号时,这真的很烦人而且不可读!特别是当它必须在IF语句或函数中出现时 if (((String)o).equals("dsadsa")) {} 避免这种情况的最佳方法是什么?将对象投射到一行中 在另一行中使用浇铸对象。解决方案是确保您的对象是以前的精确类,例如
对象
“假装”为字符串
:
Object o = new String("dsadsa");
如果要使用该对象的字符串函数,首先必须将其转换为如下字符串:
((String)o).indexOf("sad");
当有这么多括号时,这真的很烦人而且不可读!特别是当它必须在IF语句或函数中出现时
if (((String)o).equals("dsadsa")) {}
避免这种情况的最佳方法是什么?将对象投射到一行中
在另一行中使用浇铸对象。解决方案是确保您的对象是以前的精确类,例如在方法的原型中 这是最佳实践,因为它还有助于避免运行时错误 使用参数化类(泛型)会越来越容易
否则说:如果代码中有很多强制转换,那么可能存在设计问题。但是我们需要更多的代码来建议解决方案。实际上,正确使用泛型可以消除您在代码中看到的大多数强制转换 但是,如果由于某种原因您不能这样做(较旧的Java版本、遗留库),请创建一个局部变量,以便尽早执行强制转换
一种特殊情况是将对象从接口类型强制转换为其实现。这几乎总是错误的,这意味着接口设计糟糕。标准做法是始终将对象捕获到较窄类型的变量中,在您的示例中是
字符串str
变量,然后使用该变量
请注意,在第三个示例中,您不需要向下转换:o.equals(o2)
也可以工作
如果您决定研究Java泛型,您可能很快就会失望:它们通常只是将冗长的内容从downcast转移到类型声明。许多代码片段都一样长,有些在重写为泛型时甚至更长。我不这么认为。必须显式地将超类转换为子类
String str;
if(o instanceOf String){
str =(String)o;
str.indexOf("sad");
...
}
你可以利用泛型做一些危险的事情,比如
public static <T> T cast(Object o){
return (T) o;
}
这真的很烦人,但你可以这样做
public static String s(Object o){
return (String) o;
}
然后
Object o = "";
s(o).indexOf("sad");
我假设您的意思是说您的
字符串
假装是对象
您的句柄的类型为Object,它不必是Object
String s;
if (o instanceof String) {
s = (String) o;
} else {
s = null;
throw new IllegalArgumentException();
// Or take some corrective action.
}
我不推荐,但您可以这样做:
似乎您不想进行编译时类型检查。 然后只需使用脚本语言,例如Groovy,它也在JVM上运行,但不需要静态键入。
“dsadsa”。equals(someString)
就是这样做的-有效地消除了NPE的任何机会,并确保即使someString
实际上被声明为对象,也不会进行虚拟调用
您也不需要强制转换来调用equals()
除此之外,您可以使用泛型,但它们的语法过于冗长,特别是当涉及到
T selectfoobred之类的东西时(列表列表,此解决方案的比较问题,除了更难读取外,如果o不是String
,则您得到NPE而不是ClassCastException
,这对于代码维护人员来说非常混乱。如果要测试o instanceof String
(注意:instanceof中的小'o's),之前单独测试o!=null
是没有意义的。null实例无论什么
都将是false
(除此之外,我不太确定您在这里实际指的是什么。)如果你知道它是一个字符串,为什么你有一个对象?顺便说一句,你不需要在这里或其他任何地方使用新字符串(字符串)
。是的,我知道,新字符串()
只是一个例子,可以真正说明对象是字符串,而且,我很乐意避免这种情况,但是当我使用向量时,例如,我想存储字符串,它们都是对象,所以我没有选择。:/t如果您使用的是Vector,除非您使用的是j2me或java 1.4,否则您可以使用Vector,甚至ArrayList(可能)会更好地为您服务您应该尝试[Lisp](,只有一个String
分配给类型为Object
+1的变量,用于发现示例中甚至不需要强制转换。我认为,虽然泛型确实很冗长,但它们更易于阅读和解释。@biziclop它随用例而变化——集合类型是一种胜利,尤其是在combinati中另一方面,在使用增强的for.Callbacks作为lambda函数的情况下,由于弱类型推断,这是相当失败的。至少在java 7中,它没有引用为verbose:List List List=new ArrayList()变为List List=new arrarylist()@Matt true,这很有帮助,但只有在类型推断真正起作用时才有用。我已经在很多失败的例子上撞了头。@MarkoTopolnik:我通常在处理泛型时会撞到墙上。我知道他们想要向后兼容,但这会引起很多该死的麻烦,不值得。看起来像e泛型比我以前认为的要重要得多。可惜我不能使用它,因为我实际上是用JavaME编程的,它不支持泛型。x_x我认为我应该使用第二个选项。我
String s;
if (o instanceof String) {
s = (String) o;
} else {
s = null;
throw new IllegalArgumentException();
// Or take some corrective action.
}
String.class.cast(o).indexOf("sad");