I've had a small problem with splitting a String in java as follows:
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 开发者_StackOverflowVector dexListMod. 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! Am I seeing this wrong, or is this a contradiction?
Thanks.
I assume that dexListMod is an untyped List i.e. a List of Object in which case the compiler does not know at compile time that dexListMod.get(selNum-1) is a 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. e.g.
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.
Similarly, the following example is rejected by the Java compiler:
SuperClass a = new SubClass1();
a.SomeMethodInSubClass1ButNotInBaseClass(); // fails
If the compiler allowed this, you could have assigned something else to a
like:
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).
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
).
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. 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.
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. 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 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. 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.
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
, e.g. 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. 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;
// ...
}
精彩评论