LINUX.ORG.RU

[java][generic]interfaces


0

3

Добрый день. У меня вопрос, допустим имеем:

public interface SomeInterface {
}
public class SomeClass implements SomeInterface{
}

import java.io.ObjectInputStream.GetField;
import java.util.Vector;

public class Main {
	public static void main(String[] args) {
		SomeInterface[] interfaces = getSomeClassesObjects(); // That's correct
		Vector<SomeInterface> interfaces1 = getSomeClassesObjects1(); // "type mismatch: Cannot convert ... " error
		Vector<SomeInterface> interfaces2 = getSomeClassesObjects2(); // "type mismatch: Cannot convert ... " error
	}
	
	private static SomeClass[] getSomeClassesObjects() {
		return null;
	}
	
	private static Vector<SomeClass> getSomeClassesObjects1() {
		return null;
	}
	
	private static Vector<? extends SomeInterface> getSomeClassesObjects2() {
		return null;
	}
}

Почему не может преобразовать из Vector<SomeClass> в Vector<SomeInterface> в то время как с обычными массивами работает и как решить эту проблему для generic-классов? Спасибо

Потому что генерики в Жабе — это... эм... генерике в Жабе.

Java Language specification говорит нам:

Subtyping does not extend through generic types: T <: U does not imply that C<T> <: C<U>. (<: — это отношение «является подтипом» — proud_anon)

Таким образом у компилятора нет причин считать, что Vector<SomeClass>, Vector<SomeInterface> и даже Vector<? extends SomeInterface> как-либо совместимы, хотя ему и известно отношение между SomeClass и SomeInterface, и уж тем более между "? extends SomeInterface" и «SomeInterface».

Что с этим делать? Ну, я лично не знаю никакого способа, кроме как привести все к одному типу. Конечно, можно еще пойти «путем левой руки» и использовать unchecked operations, но лучше не надо. Или подождать, пока кто-нибудь скажет что-нибудь более умное, чем я, поскольку я не уверен, что это единственный способ.

proud_anon ★★★★★ ()

Vector архаичная коллекция емнип из 1.4, вроде заменена другой в 1.5, генерики вектор вроде не держит, afair

Karapuz ★★★★★ ()
public interface SomeInterface {
}
public class SomeClass implements SomeInterface{
}
public class SomeOtherClass implements SomeInterface{
}

Vector<SomeClass> foo = getSomeClassesObjects1();
Vector<SomeInterface> interfaces1 = foo; // допустим, что сработало
interfaces1.add(new SomeOtherClass());
foo.at(0); // oops

phoenix ★★★★ ()
Ответ на: комментарий от Karapuz

держит, конечно, но чаще вместо него имеет смысл использовать ArrayList, как уже было сказано выше. Если, конечно, написаный код не рассчитывает на особенности реализации Vector.

phoenix ★★★★ ()
Ответ на: комментарий от proud_anon

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

Кстати, вы уверены, что вам нужен Vector, а не ArrayList?

Да, более подходящая. Спасибо за инфу)

s0meone ()
Ответ на: комментарий от s0meone

>Т.е. сделать чтоб методы возвращали другой тип, ок.
Ну, не обязательно совсем другой, а выбрать один из этих. SomeInterface, например. Но только чтобы был один и тот же.

proud_anon ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.