Java generics T vs Object
Zastanawiałem się, jaka jest różnica między następującymi dwoma deklaracjami metody:
public Object doSomething(Object obj) {....}
public <T> T doSomething(T t) {....}
Czy jest coś, co możesz/zrobiłbyś z jednym, ale nie z drugim? Nie mogłem znaleźć tego pytania gdzie indziej na tej stronie.
7 answers
Odizolowane od kontekstu-bez różnicy. Zarówno t
, jak i obj
można wywoływać tylko metody Object
.
Ale z kontekstem-jeśli masz klasę generyczną:
MyClass<Foo> my = new MyClass<Foo>();
Foo foo = new Foo();
Potem:
Foo newFoo = my.doSomething(foo);
Ten sam kod z obiektem
Foo newFoo = (Foo) my.doSomething(foo);
Dwie zalety:
- nie ma potrzeby odlewania (kompilator ukrywa to przed tobą)
- skompiluj bezpieczeństwo Czasu, które działa. Jeśli używana jest wersja
Object
, nie będziesz mieć pewności, że metoda zawsze zwracaFoo
. Jeśli zwróciBar
, będziesz miałClassCastException
, w czasie wykonywania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-16 15:43:37
Różnica polega na tym, że w pierwszym, określamy, że wywołujący musi przekazać instancję obiektu (dowolną klasę) i otrzyma z powrotem inny obiekt (dowolną klasę, niekoniecznie tego samego typu).
W drugim, zwracany typ będzie tym samym typem, co Typ podany podczas definiowania klasy.
Example ex = new Example<Integer>();
Tutaj określamy, jaki będzie Typ T, który pozwala nam na wymuszenie większej liczby ograniczeń na klasie lub metodzie. Na przykład możemy utworzyć instancję LinkedList<Integer>
lub LinkedList<Example>
i wiemy, że kiedy wywołamy jedną z tych metod, otrzymamy z powrotem liczbę całkowitą lub przykładową instancję.
Głównym celem jest to, że kod wywołujący może określić, na jakich obiektach będzie działać Klasa, zamiast polegać na typ-castingu, aby to wymusić.
Zobacz Java Generics* z Oracle.
*Zaktualizowany Link.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 06:51:52
Różnica polega na tym, że przy metodach generycznych nie muszę rzucać i dostaję błąd kompilacji, gdy robię źle:
public class App {
public static void main(String[] args) {
String s = process("vv");
String b = process(new Object()); // Compilation error
}
public static <T> T process(T val) {
return val;
}
}
Używając obiektu zawsze muszę rzucać i nie dostaję żadnych błędów, gdy robię źle:
public class App {
public static void main(String[] args) {
String s = (String)process("vv");
String b = (String)process(new Object());
}
public static Object process(Object val) {
return val;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-02 09:28:13
W czasie pracy, nic. Ale w czasie kompilacji drugi sprawdzi Typ, aby upewnić się, że typ parametru i typ zwracanej wartości są zgodne (lub są podtypami) niezależnie od typu T (pierwszy przykład również sprawdza typ, ale każdy obiekt jest podtypem obiektu, więc każdy typ będzie akceptowany).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-05 22:15:51
T jest typem generycznym. Co oznacza, że może być zastąpiony przez dowolny kwalifikujący się obiekt w czasie wykonywania. Możesz wywołać taką metodę w następujący sposób:
String response = doSomething("hello world");
Lub
MyObject response = doSomething(new MyObject());
Lub
Integer response = doSomething(31);
Jak widać, jest tu polimorfizm.
Ale jeśli jest zadeklarowana jako return Object, nie możesz tego zrobić, chyba że wpiszesz cast things.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-05 22:17:06
Nie musisz robić dodatkowych zajęć. W pierwszym przypadku zawsze otrzymasz obiekt klasy java.lang.Obiekt, który będziesz musiał oddać do swojej klasy. W drugim przypadku T zostanie zastąpiona klasą zdefiniowaną w generic signature i nie będzie konieczne odlewanie klas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-05 22:14:40
W pierwszym przypadku pobiera parametr dowolnego typu np. string i zwraca typ foo. W drugim przypadku pobiera parametr typu foo i zwraca obiekt typu foo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-05 22:26:50