3

例如,我有一个Object“假装” String

Object o = new String("dsadsa");

如果我想使用该对象的字符串函数,首先我必须将它转换为这样的字符串:

((String)o).indexOf("sad");

当有这么多括号时,这变得非常烦人和不可读!尤其是当它必须在 IF 语句或函数中时!

if (((String)o).equals("dsadsa")) {}

避免这种情况的最佳方法是什么?

4

10 回答 10

9

一个解决方案是确保您的对象之前是一个精确的类,例如在您的方法的原型中。

这是最佳实践,因为它还有助于避免运行时错误。

使用参数化类(泛型)变得越来越容易。

否则说:如果您的代码中有很多演员表,则可能存在设计问题。但我们需要更多代码来提出解决方案。

于 2012-08-22T15:28:47.563 回答
8

将对象投射在一行中。

在另一行中使用铸造对象。

于 2012-08-22T15:28:11.407 回答
7

在实践中,正确使用泛型可以消除您过去在代码中看到的大多数类型转换。

但是如果由于某种原因你不能这样做(旧的 Java 版本,遗留库),请创建一个局部变量,尽早在其中进行转换。

一种特殊情况是当您将对象从接口类型转换为其实现时。这几乎总是错误的,意味着界面设计不当。

于 2012-08-22T15:28:48.403 回答
5

标准做法是始终将您的对象捕获到更窄类型的变量中,在您的情况下是一个String str变量,然后使用它。

请注意,在您的第三个示例中,您不需要向下转换:o.equals(o2)也可以。

如果您决定学习 Java 泛型,您可能很快就会失望:它们通常只是将冗长的内容从向下转换转换为类型声明。当重写为泛型时,许多代码片段都一样长,有些甚至更长。

于 2012-08-22T15:30:21.747 回答
2

我假设你的意思是说你String的假装是Object.

您的句柄是 Object 类型的,它不必是。

  1. 如果您使用的是 Object 类型,因为这是您的方法获取的参数,请考虑将参数类型更改为 String,如果您实际上需要一个 String。
  2. 如果这来自一个集合,请考虑将集合更改为使用泛型,以便您可以将集合定义为字符串类型。
  3. 如果由于某种原因您无法更改传入对象的类型,请验证它实际上是一个字符串,并将其转换为另一个字符串类型的变量。

对于第三个选项,这就是代码的样子。

String s;
if (o instanceof String) {
    s = (String) o;
} else {
    s = null;
    throw new IllegalArgumentException();
    // Or take some corrective action.
}
于 2012-08-22T15:37:54.887 回答
1

我不这么认为。您必须明确地将超类转换为子类。

String str;

if(o instanceOf String){
   str =(String)o;
   str.indexOf("sad");
   ...
}
于 2012-08-22T15:31:50.730 回答
1

你可以利用泛型做一些危险的事情,比如

public static <T> T cast(Object o){
    return (T) o;
}

这使您可以执行以下操作

Object o="";
String s = cast(o);

这真的很hacky,但你可以做类似的事情

public static String s(Object o){
    return (String) o;
}

进而

    Object o = "";
    s(o).indexOf("sad");
于 2012-08-22T15:36:51.213 回答
1

我不推荐它,但你可以这样做:

String.class.cast(o).indexOf("sad");
于 2012-08-22T16:28:35.657 回答
0

似乎您不想进行编译时类型检查。然后只需使用脚本语言,例如 Groovy,它也可以在 JVM 上运行,但不需要静态类型。

于 2012-08-22T23:18:20.770 回答
0

"dsadsa".equals(someString)它是如何完成的 - 有效消除了 NPE 的任何机会,并确保即使someString实际上被声明为对象也没有虚拟调用。

你也不需要 cast 来调用equals().

除此之外,您可以使用泛型,但它们的语法过于冗长,尤其是在涉及到类似的东西时<T extends Foo &Bar> T selectFooBared(List<java.lang.ref.Reference<T>> list, Comparator<? super T> c);

于 2012-08-25T12:24:23.810 回答