简体   繁体   English

Java-拆分字符串问题

[英]Java - splitting String problem

I've had a small problem with splitting a String in java as follows: 我在用java拆分字符串时遇到了一个小问题,如下所示:

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

The first line prints the class name of the Object returned from the index of selNum -1 in the Vector dexListMod. 第一行打印从Vector dexListMod中的selNum -1索引返回的Object的类名称。 This outputs the following in the console: 这将在控制台中输出以下内容:

java.lang.String

The second line defines a String of this same Object to split() later but, and this is the problem, the compiler says that they are incompatible types! 第二行定义了相同对象的String,稍后再进行split(),但这就是问题所在,编译器说它们是不兼容的类型! Am I seeing this wrong, or is this a contradiction? 我是看错了这还是矛盾?

Thanks. 谢谢。

I assume that dexListMod is an untyped List ie a List of Object in which case the compiler does not know at compile time that dexListMod.get(selNum-1) is a String. 我假设dexListMod是一个无类型的列表,即对象列表,在这种情况下,编译器在编译时不知道dexListMod.get(selNum-1)是一个String。 At runtime the Object can report that it is actually a String, this is polymorphism in action. 在运行时,对象可以报告它实际上是一个字符串,这实际上是多态性。

What you need to do is cast it to a type or use a typed List. 您需要执行的操作是将其强制转换为类型或使用类型列表。 eg 例如

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

The problem is that what matters for Java compiler is the static type of the object, not what it actually is at runtime. 问题在于,对于Java编译器而言,重要的是对象的静态类型,而不是运行时的实际类型。

Similarly, the following example is rejected by the Java compiler: 同样,Java编译器拒绝以下示例:

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

If the compiler allowed this, you could have assigned something else to a like: 如果编译器允许这样做,您可能已经将其他内容分配给a

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

In the general case, it's theoretically impossible to find the exact runtime type of a variable at compile time. 在一般情况下,理论上不可能在编译时找到变量的确切运行时类型。 The compiler remains conservative and simply fails to compile instead of assuming correctness and possibly failing at runtime (dynamic languages like Python usually choose the opposite design decision: assume correctness and potentially failing at runtime). 编译器保持保守,只是无法编译,而不是假设其正确性并可能在运行时失败(像Python这样的动态语言通常会选择相反的设计决策:假设正确性并在运行时可能失败)。

Your code snippet essentially demonstrates the same thing, where the return type of dexListMod.get method is probably Object , and it returns a String instance (which is derived from Object ). 您的代码段实质上演示了同一件事,其中dexListMod.get方法的返回类型可能是Object ,并且它返回String实例(从Object派生)。

If you are sure about the runtime type of an object, Java requires you to be explicit about it and take the responsibility to manually cast it to the type you expect. 如果您确定对象的运行时类型,则Java要求您明确说明该对象,并负责将其手动转换为所需的类型。 Of course, the cast can potentially fail at runtime and throw an exception. 当然,强制转换可能会在运行时失败并引发异常。

If you have not used Generics, the list will return Object, you will need an explicit cast. 如果尚未使用泛型,则列表将返回Object,则需要显式强制转换。

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

The problem is that in the second line it's expected to have a String type. 问题是在第二行中应该具有String类型。 Your vector hasn't been parametrized. 您的向量尚未参数化。 So the compiler doesn't know which types of objects you store in it 所以编译器不知道您存储在其中的对象类型

If you store strings in the vector than you need to cast the value to String type 如果将字符串存储在向量中,则需要将值强制转换为String类型

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

Try this and see what it outputs: 试试这个,看看它输出什么:

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

The type of the object returned from that call doesn't have to necessarily be a String. 从该调用返回的对象的类型不必一定是String。 It could return an Object. 它可以返回一个对象。 Even though that Object is actually a String (as shown by your call to dexListMod.get(selNum-1).getClass().getName()), it must first be cast as a String before you can use it as such. 即使该对象实际上是一个字符串(如对dexListMod.get(selNum-1).getClass()。getName()的调用所示),也必须首先将其强制转换为字符串,然后才能使用它。

You haven't stated the declaration of dexListMod , but I assume that it its without any generic type parameter ( Vector dexListMod ) or with a type parameter that is a supertype of String , eg Vector<Object> dexListMod . 您尚未声明dexListMod的声明,但是我假设它没有任何泛型类型参数( Vector dexListMod )或具有String的超类型的类型参数,例如Vector<Object> dexListMod The get method of such declaration does not return java.lang.String , but a supertype which may or may not be assignment compatible with String. 此类声明的get方法不会返回java.lang.String ,而是可以或可以不与String赋值兼容的超类型。 The compiler enforces static assignment compatibility and therefore gives you this error message. 编译器强制执行静态分配兼容性,因此会显示此错误消息。

Use a cast and eventually a type check to assign the result: 使用强制转换并最终使用类型检查来分配结果:

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;
  // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM