【问题标题】:Java - splitting String problemJava - 拆分字符串问题
【发布时间】:2010-11-11 10:18:59
【问题描述】:

我在java中拆分字符串时遇到了一个小问题,如下所示:

System.out.println(dexListMod.get(selNum-1).getClass().getName());
String dexListTempString = dexListMod.get(selNum-1);

第一行打印从 Vector dexListMod 中 selNum -1 的索引返回的 Object 的类名。这会在控制台中输出以下内容:

java.lang.String

第二行定义了一个相同对象的 String 到 split() 之后,但是,这就是问题所在,编译器说它们是不兼容的类型!是我看错了,还是自相矛盾?

谢谢。

【问题讨论】:

    标签: java type-conversion


    【解决方案1】:

    我假设 dexListMod 是一个无类型列表,即一个对象列表,在这种情况下,编译器在编译时不知道 dexListMod.get(selNum-1) 是一个字符串。在运行时,对象可以报告它实际上是一个字符串,这就是多态性。

    您需要做的是将其转换为类型或使用类型化列表。例如

    if (dexListMod.get(selNum-1) instanceof String) {
        String s = (String) dexListMod.get(selNum-1);
        System.out.println(s);
    }
    

    【讨论】:

    • @iamthepiguy:如果任何答案对您有所帮助,请考虑接受它,将您的问题标记为已回答。
    • 抱歉,没看懂。
    【解决方案2】:

    问题在于,对于 Java 编译器而言,重要的是对象的静态类型,而不是运行时的实际类型。

    同样,以下示例被 Java 编译器拒绝:

    SuperClass a = new SubClass1();
    a.SomeMethodInSubClass1ButNotInBaseClass(); // fails
    

    如果编译器允许这样做,您可以为 a 分配其他内容,例如:

    SuperClass a = new SubClass1();
    a = new SubClass2(); // it doesn't have the method!
    a.SomeMethodInSubClass1ButNotInBaseClass(); // would fail at runtime if allowed
    

    在一般情况下,理论上不可能在编译时找到变量的确切运行时类型。编译器保持保守,只是无法编译,而不是假设正确性并可能在运行时失败(像 Python 这样的动态语言通常选择相反的设计决策:假设正确性并可能在运行时失败)。

    您的代码 sn-p 本质上演示了同样的事情,其中​​dexListMod.get 方法的返回类型可能是Object,它返回一个String 实例(派生自Object)。

    如果您确定对象的运行时类型,Java 要求您明确说明它并负责手动将其转换为您期望的类型。当然,强制转换可能会在运行时失败并引发异常。

    【讨论】:

      【解决方案3】:

      如果您没有使用泛型,列表将返回 Object,您将需要显式转换。

      if(dexListMod.get(selNum-1) instanceof java.lang.String){
        String dexListTempString = (String)dexListMod.get(selNum-1);
      }
      

      【讨论】:

        【解决方案4】:

        问题是在第二行中它应该有一个字符串类型。您的矢量尚未参数化。所以编译器不知道你在里面存储了哪些类型的对象

        如果将字符串存储在向量中,则需要将值转换为字符串类型

        String dexListTempString = (String) dexListMod.get(selNum-1);
        

        【讨论】:

          【解决方案5】:

          试试这个,看看它的输出:

          String dexListTempString;
          System.out.println(dexListTempString.getClass().getName());
          

          【讨论】:

            【解决方案6】:

            从该调用返回的对象类型不一定是字符串。它可以返回一个对象。即使该对象实际上是一个字符串(如您对 dexListMod.get(selNum-1).getClass().getName() 的调用所示),它必须首先转换为字符串,然后才能使用它。

            【讨论】:

              【解决方案7】:

              您没有声明dexListMod,但我假设它没有任何泛型类型参数(Vector dexListMod)或带有String 超类型的类型参数,例如Vector<Object> dexListMod。这种声明的get 方法不返回java.lang.String,而是一个超类型,它可能是也可能不是与String 兼容的赋值。编译器强制执行静态赋值兼容性,因此会显示此错误消息。

              使用强制转换并最终使用类型检查来分配结果:

              Object val = dexListMod.get(selNum - 1)
              if (val == null || val instanceof String) {
                // this if contains a check for null because null instanceof Type is always false.
                // If you want only non-null Strings, then just use "if (val instanceof String)"
                String dexListTempString = (String)val;
                // ...
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-10-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多