Dlaczego tablice są obiektami, ale nie mogą być używane jako klasa bazowa?

Specyfikacja języka Java określa, że

W języku programowania Java tablice są obiektami (§4.3.1), są tworzone dynamicznie i mogą być przypisane do zmiennych typu Object (§4.3.2). Wszystkie metody klasy Object mogą być wywoływane w tablicy.

Więc biorąc pod uwagę, że tablice są obiektami-Dlaczego projektanci Javy podjęli decyzję, aby nie zezwalać na dziedziczenie i nadpisywanie z niej, na przykład, toString() albo equals()?

Bieżąca składnia nie Zezwalaj na tworzenie anonimowych klas z tablicą jako klasą bazową, ale nie sądzę, aby to było powodem ich decyzji.

Author: Community, 2014-12-16

4 answers

Java była kompromisem między językami nie-obiektowymi a bardzo wolnymi językami tamtych czasów, w których wszystko było obiektem (pomyśl o Smalltalk ).

Nawet w nowszych językach, posiadanie szybkiej struktury na poziomie języka dla tablic (i zazwyczaj map) jest uważane za cel strategiczny. Większość ludzi nie chciałaby wagi dziedzicznego obiektu dla tablic, a na pewno nikt nie chciał tego przed rozwojem JVM, takim jak JIT.

Dlatego tablice, podczas gdy jako obiekty, nie zostały zaprojektowane jako instancje klasy ( "obiekt jest instancją klasy lub tablicą" ). Byłoby niewiele korzyści z możliwości nadpisania metody na tablicy, a na pewno nie na tyle wielkiej, aby zrównoważyć potrzebę sprawdzenia, czy odpowiednia metoda może być zastosowana (i moim zdaniem nie na tyle wielkiej, aby zrównoważyć zwiększoną trudność w czytaniu kodu, podobną do tego, co się dzieje, gdy nadpisujesz operatorów).

 35
Author: Denys Séguret,
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-12-16 23:20:42

Natknąłem się pod maską-obiekty i tablice co wyjaśnia prawie wszystko, co musisz wiedzieć o tym, jak JVM obsługuje tablice. W JVM tablice są obsługiwane za pomocą specjalnych bajtowych kodów , nie tak jak inne obiekty, które znamy.

W zestawie instrukcji JVM wszystkie obiekty są tworzone i dostępne z tym samym zestawem kodĂłw opcodăłw, z wyjÄ ... tkiem dla tablic. W Javie tablice są pełnowartościowych obiektów, oraz, jak każdy inny obiekt w Program Java, są tworzone dynamicznie. Odniesienia do tablic mogą być używane w dowolnym miejscu wywołane jest odniesienie do obiektu typu, a każda metoda obiektu może być wywoływane na tablicy. Jednak w wirtualnej maszynie Javy tablice są obsługiwane za pomocą specjalnych bajtodów .

Podobnie jak w przypadku innych obiektów, tablice nie mogą być zadeklarowane jako lokalne zmienne ; Tylko odwołania do tablicy mogą. Same obiekty tablicy zawsze zawiera tablicę typów prymitywnych lub tablicę obiektów referencje. Jeśli zadeklarujesz tablicę obiektów, otrzymasz tablicę odniesienia do obiektów. Same obiekty muszą być wyraźnie utworzone z nowymi i przypisanymi do elementów tablicy.

Tablice są tworzone dynamicznie i służą jako kontener przechowujący (stałą) liczbę obiektów tego samego typu. Wygląda na to, że tablice nie są jak każdy inny obiekt i dlatego są traktowane inaczej.

 16
Author: Maroun,
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-12-16 23:21:54

Chciałbym zwrócić uwagę na ten Artykuł. Wygląda na to, że tablice i Obiekty podążają za różnymi kodami opcodes. Nie mogę szczerze podsumować tego bardziej niż to, jednak wydaje się, że tablice nie są po prostu traktowane jako Objects, jak zwykle jesteśmy przyzwyczajeni, więc nie dziedziczą metod Object.

Pełne podziękowania dla autora tego postu, ponieważ jest to bardzo ciekawa lektura, zarówno krótka, jak i szczegółowa.


Po dalszym zagłębianiu się w Temat przez wiele źródeł postanowiłem dać bardziej rozbudowana wersja mojej poprzedniej odpowiedzi.

Pierwszą rzeczą, aby zauważyć, że instancje obiektów I tablic są bardzo różne w JVM, ich odpowiedni bajt kod.

Obiekt:

Object instancjacja następuje po prostym Opcode new, który jest kombinacją dwóch operandów - indexbyte1 & indexbyte2. Po utworzeniu instancji JVM wypycha odniesienie do tego obiektu na stack. Dzieje się tak dla wszystkich obiektów niezależnie od ich typów.


Tablice:

Array Opcodes (dotyczy instancji tablicy) są jednak podzielone na trzy różne kody.

newarray - w tym celu należy utworzyć nową tablicę z typami typowymi wskazywanymi przez atype, wypycha obiekt nowej tablicy

newarray opcode jest używany przy tworzeniu tablic zawierających prymitywne typy danych (byte short char int long float double boolean) zamiast odniesienia do obiektów.

anewarray - wyświetlanie długości, przydziela nową tablicę obiektów klasy wskazywanych przez indexbyte1 i indexbyte2, wypycha obiekt nowej tablicy

anewarray opcode jest używany do tworzenia tablic odniesień do obiektów

multianewarray - wyskakuje wymiary liczba długości tablicy, przydziela nową wielowymiarową tablicę klasy wskazaną przez indexbyte1 i indexbyte2, wypycha objectref nowej tablicy

multianewarray instrukcja jest używana przy przydzielaniu tablic wielowymiarowych


Obiekt może być instancją klasy lub tablicą.

Weź z Oracle Docs

Instancja klasy jest jawnie tworzona przez wyrażenie tworzenia instancji klasy

ale

Tablica jest jawnie tworzona przez wyrażenie tworzenia tablicy

Idzie to w parze z informacją o kodach opcodes. Tablice są po prostu nie interfejsy klasy, ale zamiast tego są jawnie utworzone przez wyrażenie tworzenia tablicy, więc naturalnie niejawnie nie będą mogły dziedziczyć i/lub nadpisywać Object.

Jak widzieliśmy, nie ma to nic wspólnego z faktem, że tablice mogą posiadać prymitywne typy danych. Po zastanowieniu się nad tym, nie jest zbyt często natykać się na sytuacje, w których ktoś mógłby chcieć toString() lub equals(), jednak nadal było to bardzo interesujące pytanie, aby spróbować i odpowiedz.


Zasoby:

Oracle-Docs rozdział 4.3.1

Oracle-Docs chapter 15.10.1

Artima-UnderTheHood

 8
Author: Juxhin,
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-12-16 21:04:54

Istnieje wiele klas w standardowej bibliotece java, których nie można podklasować, tablice nie są jedynym przykładem. Rozważmy String, lub StringBuffer, lub którykolwiek z "prymitywnych owijarek", jak Integer, lub Double. Istnieją optymalizacje, które wykonuje JVM w oparciu o znajomość dokładnej struktury tych obiektów, gdy zajmuje się nimi (jak rozpakowanie elementów pierwotnych lub manipulowanie pamięcią tablicy na poziomie bajtów). Gdyby można było nadpisać cokolwiek, nie byłoby to możliwe, a wpływ na wydajność programów bardzo źle.

 2
Author: Dima,
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-12-16 12:53:54