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.

Author: newacct, 2011-03-06

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 zwraca Foo. Jeśli zwróci Bar, będziesz miał ClassCastException, w czasie wykonywania.
 78
Author: Bozho,
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.

 8
Author: Adam,
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;
    }
}
 6
Author: user1883212,
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).

 2
Author: Jonathan,
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.

 2
Author: adarshr,
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.

 1
Author: Andrey Adamovich,
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.

 0
Author: fastcodejava,
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