2013-03-17 2 views
2

Я пытаюсь отправить список объектов через сокет.Получить базовый/родительский/суперкласс из дочернего/унаследованного класса

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

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

// subClassList is an ArrayList<SubClass> 
ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>(); 
for(SubClass subClass: subClassList) { 
    // cast to the base class 
    baseClassList.add((BaseClass)subClass); 
} 

Это, однако, не работает, как я все еще получаю такое же исключение NotSerializableException. От отладки кода я вижу, что новый список по-прежнему является списком подкласса, хотя он и был отличен.

Есть ли способ достичь того, что я пытаюсь сделать?

ответ

1

Кастинг ссылка не меняет типа реального объекта:

String foo = "hello"; 
Object bar = (Object) foo; 
System.out.println(bar); // Hello 
System.out.println(bar.getClass()); // java.lang.String 

Если вы хотите только есть экземпляр базового класса, можно создать конструктор базового класса, который просто создает новый экземпляр базового класса данного экземпляра этого, без пытается выполнить какой-либо глубокой копии:

public BaseClass(BaseClass other) { 
    this.x = other.x; 
    this.y = other.y; 
    this.z = other.z; 
    // etc 
} 

Затем в коде вы шоу п:

baseClass.add(new BaseClass(subClass)); 
0

Ваш подход не работает, потому что даже если вы можете использовать переменную суперкласса для обозначения объекта подкласса, сам объект типа суб класса.

Лучший способ - либо сериализовать подкласс, либо извлечь данные из подкласса и записать их во вновь созданный суперкласс. Просто используйте метод статической утилиты, чтобы сделать сборку преобразования в подкласс ...

0

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

String s = "hello"; 
Object o = s; // no cast needed 

понижающее приведение необходимо, и будет работать только в случае, если объект имеет тип, который вы приводите его к:

Object o = "hello"; 
Object o2 = Integer.valueOf(5); 
String s = (String) o; // OK because o is a String 
String s2 = (String) o2; // ClassCastException, because o2 is not a String. 

Таким образом, ваш код эквивалентен

ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>(); 
for(SubClass subClass: subClassList) { 
    // cast to the base class 
    baseClassList.add(subClass); 
} 

Вы должны создать новый объект нового типа, используя конструктор копирования:

ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>(); 
for(SubClass subClass: subClassList) { 
    // cast to the base class 
    baseClassList.add(new BaseClass(subClass)); 
} 
0

Ваш вопрос воплощает противоречие в терминах. Если базовый класс является Serializable, то все его производные классы. Если ваш производный класс содержит ссылки на несериализуемые объекты, просто сделайте их переходными.

Смежные вопросы