Java - проблема расщепления строки - PullRequest
1 голос
/ 11 ноября 2010

У меня была небольшая проблема с разбиением строки в Java следующим образом:

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

В первой строке выводится имя класса объекта, возвращаемого из индекса selNum -1 в векторе dexListMod. Это выводит следующее в консоли:

java.lang.String

Вторая строка определяет строку этого же объекта для split () позже, но, и это проблема, компилятор говорит, что они несовместимы! Я вижу это неправильно, или это противоречие?

Спасибо.

Ответы [ 7 ]

3 голосов
/ 11 ноября 2010

Я предполагаю, что dexListMod является нетипизированным списком, то есть списком объектов, и в этом случае компилятор не знает во время компиляции, что dexListMod.get (selNum-1) является строкой. Во время выполнения объект может сообщить, что он на самом деле является строкой, это полиморфизм в действии.

Что вам нужно сделать, это привести его к типу или использовать типизированный список. например,

if (dexListMod.get(selNum-1) instanceof String) {
    String s = (String) dexListMod.get(selNum-1);
    System.out.println(s);
}
2 голосов
/ 11 ноября 2010

Проблема в том, что для компилятора 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, обычно выбирают противоположное проектное решение: предполагают правильность и потенциально терпят неудачу во время выполнения).

Ваш фрагмент кода по существу демонстрирует то же самое, где тип возвращаемого значения dexListMod.get метода, вероятно, Object, и он возвращает экземпляр String (который является производным от Object).

Если вы уверены в типе объекта во время выполнения, Java требует, чтобы вы были откровенны в этом и взяли на себя ответственность вручную привести его к типу, который вы ожидаете. Конечно, приведение может привести к сбою во время выполнения и вызвать исключение.

1 голос
/ 11 ноября 2010

Проблема в том, что во второй строке ожидается тип String. Ваш вектор не был параметризован. Таким образом, компилятор не знает, какие типы объектов вы храните в нем

Если вы храните строки в векторе, вам нужно привести значение к типу String

String dexListTempString = (String) dexListMod.get(selNum-1);
1 голос
/ 11 ноября 2010

Если вы не использовали Generics, список вернет Object, вам потребуется явное приведение.

if(dexListMod.get(selNum-1) instanceof java.lang.String){
  String dexListTempString = (String)dexListMod.get(selNum-1);
}
0 голосов
/ 11 ноября 2010

Вы не указали объявление 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;
  // ...
}
0 голосов
/ 11 ноября 2010

Тип объекта, возвращаемого этим вызовом, не обязательно должен быть String. Это может вернуть объект. Даже если этот объект на самом деле является строкой (как показывает ваш вызов dexListMod.get (selNum-1) .getClass (). GetName ()), он должен сначала быть приведен как строка, прежде чем вы сможете использовать его как таковой.

0 голосов
/ 11 ноября 2010

Попробуйте и посмотрите, что он выводит:

String dexListTempString;
System.out.println(dexListTempString.getClass().getName());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...