Tablice obiektowe

1

Gdy tworzymy obiekt jakiejś klasy to piszemy:

Abc  x = new Abc 

i mamy obiekt klasy Abc do którego odnosi się zmienna x która zawiera do niego referencje. I ten obiekt ma tam jakieś swoje własciwości itd.

Gdy tworzymy tablice ze zmiennymi referencyjnymi to piszemy

Abc [] b = new Abc []

Jest to bardzo podobne do tworzenia obiektu danej klasy, ale tablica zawiera tylko referencje do poszczególnych obiektów klasy Abc.
Z tego co wyczytałem tablica sama w sobie też jest obiektem. Tylko pytanie jakiej klasy tablica jest obiektem??
(Na pewno nie jest obiektem klasy Abc, ponieważ sam obiekt klasy Abc ma swoje określone właściwości a tablica zawiera tylko same referencje do obiektów a nie ich właściwości)

(nie wiem czy dobrze wyraziłem swoje pytanie żebyście mnie zrozumieli ale mam nadzieje że rozumiecie moje pytanie)

2

Tylko pytanie jakiej klasy tablica jest obiektem??
Odpowiedź na Twoje pytanie ;)

Abc [] b = new Abc []
System.out.println(b.getClass());
 
0

Możesz odpowiedzieć po ludzku (z wytłumaczeniem) jak pytam??

1

To sformułuj odpowiednio pytanie, wtedy dostaniesz swoją odpowiedź. W Twoim poście jest tylko jedno pytanie - prosiłeś o to, jaka to jest klasa...

Doczytać możesz np. tutaj jeszcze:
http://stackoverflow.com/questions/6867131/getclass-method-java-with-array-types

0

Skoro tablice są obiektami - to jakich klas?

0

Pytam w miejscu dla początkujących i oczekuje jasnych czasami nawet łopatologicznych odpowiedzi.
A wy mówicie poszukaj sobie w internecie. To tak samo wygląda jak by uczeń pytał sie nauczyciela a on ,u mówi poszukaj sobie w internecie. W takim wypadku nauczyciel jest nie potrzebny. Tak samo z tym forum. Po jaka cholerę to forum jest jak każecie sobie szukać na internecie.
Wynika z tego że forum jest nie potrzebne bo i tak jedyna odpowiedź jaka mogę tutaj dostać to poszukaj sobie na internecie

0

Gdybym znalazł to bym tu nie pytał.

0

No własnie nie dał mi prostej odpowiedzi. Może by ktos napisał co i jak sie dzieje, g**no mi z kodu który jak wywołam to mi pokazuje jakies dziwactwa. Nie możecie normalnie słownie napisać co sie dzieje i skąd to sie bierze. Kod nie tłumaczy, tylko daje sam wynik.

0

Postarałem się sam poszukać, bo mnie to zdenerwowało, i co znalazłem: tablice nie są obiektami żadnych klas. Są po prostu obiektami.

Jak jest napisane: "An object is a class instance OR an array" (docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.3.1). W tym też linku widać niżej kolejne rozróżnienie - obiekty tablic (=tablice) są tworzone inaczej niż instancje klas.

Poza tym: "In the Java programming language, arrays are objects (...)" (docs.oracle.com/javase/specs/jls/se7/html/jls-10.html). Jeszcze w innym miejscu: "An array is a container object (...)" (https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html).

0

Z drugiej jednak strony można sparametryzować szablon tablicą:

class Szablon<Typ> {}
(...)
Szablon<Integer[]> cośtam = new Szablon<>();

Można też wywołać .getClass() na tablicy i dowiedzieć się jakiego jest typu.

0

@Michał Bodziony

Tablica jako ogólne pojęcie w Javie to tylko abstrakcyjny (w sensie ogólnym) koncept - czyli taki, jakiego w kodzie nigdy nie zobaczysz. Tablica w Javie bez powiązanego z nią typu zawartości nie istnieje, tak więc nie może być mowy o jednym typie tablicowym - każdy rodzaj tablicy to osobny typ o nazwie tworzonej dynamicznie wg konwencji opisanej w linku zamieszczonym we wcześniejszych postach.

2

Przecież getClass wyświetli np. coś takiego: class [Ljava.lang.String;, czyli poznamy jedynie typ zmiennej (który i tak znamy), a nie dowiemy się, jakiej klasy tablica jest obiektem. :|

Tak na logikę - skoro tablice są obiektami, a każdy obiekt musi mieć typ, to gdzieś w hierarchii powinna istnieć klasa definiująca bazowy typ tablicowy. Albo wiele takich klas. Albo nie ma takiej klasy, a tablice to jakaś magia kompilatora, który zamienia ich deklaracje na plik XML i ExceptionFactory, ale to też by należało opisać.

Proste pytanie, a Wy zamiast udzielić prostej odpowiedzi, albo wrzucacie bezsensowne kawałki kodu, albo czepiacie się autora, że w ogóle śmiał spytać o coś, co dla Was jest oczywiste - chociaż chyba jednak nie jest.

1

getClass na tablicy zwróci obiekt klasy Class i dla tablic takich samych typów zwróci tą samą instancję klasy Class. Nie ma bazowej klasy dla tablic. Bezpośrednią nadklasą dla typu tablicowego jest Object.

Tablice nie mają swoich plików źródłowych, ale z drugiej strony plików źródłowych nie mają też np lambdy. Lambdy mają zdefiniowane tylko ciało w plikach .java, a klasy tworzone są w czasie wykonywania. Można to sprawdzić w ten sposób:

import java.util.function.Consumer;

public class Main {

    public static void main(String[] args) {
        Consumer<String> consumer = x -> System.out.println(x);
        
        System.out.println(consumer.getClass().getName());
    }
}

Jakkolwiek by na to nie spojrzeć to i tak nie widzę sensu filozofowania. Nawet zakładając, że tablice są różowymi słoniami (ale dalej dziedziczącymi po Object) niczego się nie zmieni.

2
somekind napisał(a):

Przecież getClass wyświetli np. coś takiego: class [Ljava.lang.String;, czyli poznamy jedynie typ zmiennej (który i tak znamy), a nie dowiemy się, jakiej klasy tablica jest obiektem. :|

Nie, dowiesz się też, jaki jest typ tablicy, jest to:
[Ljava.lang.String
A to, że jego nazwa jest tworzona na bazie typu elementów tablicy, nie oznacza, że możesz zignorować [L w nazwie typu i stwierdzić, że getClass() zwraca tylko typ elementów tablicy. Jest to wewnętrzna nazwa (taki alias powiedzmy), znaczy tyle, co String[] (co też jako całość jest nazwą typu).

Tak na logikę - skoro tablice są obiektami, a każdy obiekt musi mieć typ, to gdzieś w hierarchii powinna istnieć klasa definiująca bazowy typ tablicowy.

Nie, nie powinna - jak pisałem wyżej, ogólny, nieabstrakcyjny typ tablicowy nie ma sensu (jeśli chodzi o języki statycznie typowane przynajmniej). W takim C# na przykład między Object a typami tablicowymi istnieje co prawda jeszcze klasa abstrakcyjna Array, ale to nadal nic nie zmienia, jak sama nazwa wskazuje jest to dodatkowa klasa nadrzędna, a nie klasa, której instancjami są tablice (zawiera ona głównie gettery i settery wspólnych właściwości tablic i mnóstwo metod statycznych - stanowi de facto odpowiednik klasy java.util.Arrays), same tablice mają własne typy.

Java: http://ideone.com/Y5v2oZ
C#: http://ideone.com/4HM2NH
Jak widać różnica kosmetyczna.

Albo wiele takich klas.

Raczej nieskończenie wiele ;) Ile typów danych, które są przechowywane w tablicach tyle musiałoby być klas tablicowych (a, że typów danych przechowywanych w tablicach może być nieskończenie wiele to sam widzisz ile to ma sensu).

Albo nie ma takiej klasy, a tablice to jakaś magia kompilatora, który zamienia ich deklaracje na plik XML i ExceptionFactory, ale to też by należało opisać.

Coś w tym stylu, nie ma (bo nie może być) predefiniowanych typów tablic, są one tworzone dynamicznie na podstawie deklaracji programisty. Jak to się technicznie odbywa - nie wiem, jest to mało istotne dla zrozumienia tematu (choć niewątpliwie ciekawe, kiedyś o tym poczytam).

Proste pytanie, a Wy zamiast udzielić prostej odpowiedzi, albo wrzucacie bezsensowne kawałki kodu, albo czepiacie się autora, że w ogóle śmiał spytać o coś, co dla Was jest oczywiste - chociaż chyba jednak nie jest.

Jasne, takie trywialne to to nie jest, natomiast postawa autora tematu skutecznie zniechęca do tłumaczenia czegokolwiek - stąd to zbywanie na początku (przynajmniej jeśli o mnie chodzi).

(Jeśli coś źle napisałem to proszę o sprostowanie, nie jestem Javowcem).

3

Tablica obiektów jest typu tablica obiektów.

Random[] tab = new Random[3];
System.out.println(tab.getClass().getTypeName());  //=> java.util.Random[]
0

Proszę mi wyjaśnić co w mojej postawie skutecznie zniechęca do tłumaczenia czegokolwiek, chetnie sie dowiem, może o czyms nie wiem i robie źle że nie chcecie mi nic tłumaczyc.

0

Czytam sobie ksiażke i różne artykuły w internecie na temat Javy. Można sie nauczyć na pamięć zasad i być dobrym w pisaniu programów.
Ale w takim przypadku nie zawsze sie rozumie co sie tak naprade dzieje.
Spróbuje wyjaśnić jeszcze raz o co mi chodzi. Gdy stworzymy sobie obiekt jakiejs klasy, bedzie on miał w sobie te pola, metody jakie dała mu jego forma czy klasa. Analogia do foremek i ciastek. Jaka bedzie forma takie wyjdzie ciastko.
W pewnym momencie doczytałem że tablica też jest obiektem i tyle było na ten temat. Tylko zastanowiło mnie jakiej klasy tablica jest obiektem? Co mam na mysli? a no to że gdy stworzymy pojedynczy obiekt jakiejś klasy to on jest taki jak go "stworzyła" dana klasa.
Zaś tablica jest obiektem w którym znajduje sie tylko zestaw samych referencji do obiektów a sama tablica też jest referencją, która zostaje przypisana do zmiennej tablicowowej o nazwie tablicy. A przecież deklaracja i inicjacja tablicy jest prawie identyczna jak obiektu (z ta różnicą że w tablicach piszemy dodatkowo znaki nawiasów: [] )

A wiec używając podobnego wywołania tworzenia tablic i obiektów. Przykład:

Abc x = new Abc
  • obiekt z referencją x
Abc []x = new Abc[

] - tablica z nazwą x

Skoro tablica zawiera same tylko referencje do obiektów to tablica nie jest obiektem klasy Abc bo jak by była obiektem klasy Abc to musiała by zawierać takie same pola metody idt jak obiekt tej klasy, a jednak tablica zawiera tylko same referencje do obiektów danej klasy czyli nie jest taka sama jak obiekt tej klasy a jednak też jest obiektem. Tylko pytanie obiektem jakiej klasy??

================================================================================
Chyba że tablica nie jest obiektem a tylko zestawem samych referencji o wspólnej czołowej nazwie różniącej sie tylko numerem indeksu
np.

Abc []x = new Abc[3]
  • i że takim wywołaniem automatycznie utworzyliśmy zestaw 3 zmiennych referencyjnych:
x[0];
x[1];
x[2];

zamiast trzy razy pisać:

Abc x0;
Abc x1;
Abc x2;

Ale znowu patrząc logicznie w wywołaniu Abc []x = new Abc[3] użyliśmy konstruktora który tworzy obiekt.

Zainteresowało mnie to trochę, bo jest tutaj trochę brak logiki i spójności.

Może ktoś będzie miał dobry humor dziś i napisze to i owo na ten temat, prostym językiem rozjaśniającym jak to naprawdę jest? (bez zbędnej filozofii)
Pozdro.

Dodatkowo powiem że w moim kodzie wywołanie metody getClass() na tablicy dało taki wynik:
class [Linheritance.Employee; - którego nie rozumiem co on zwraca.

0

Ale znowu patrząc logicznie w wywołaniu Abc []x = new Abc[3] użyliśmy konstruktora który tworzy obiekt.

Zainteresowało mnie to trochę, bo jest tutaj trochę brak logiki i spójności.

Może ktoś będzie miał dobry humor dziś i napisze to i owo na ten temat, prostym językiem rozjaśniającym jak to naprawdę jest? (bez zbędnej filozofii)
Pozdro.

Tablicę dowolnego typu możesz sobie stworzyć dynamicznie przez wywołanie java.lang.reflect.Array.newInstance

Nie tworzy się ręcznie klas dla tablic, by móc tworzyć tablice. Po co zresztą ktokolwiek miałby to robić? Jak miałaby wyglądać taka klasa?

Scala wprowadza klasę Array, która istnieje sobie tylko na etapie kompilacji. Potem jest zamieniania na zwykłe Javowe tablice. Kod jest tutaj: https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Array.scala#L503 . Widać, że wszystkie metody rzucają Error, ale to jest OK, bo i tak to jest wycinane na etapie kompilacji (tzn klasa Array jest traktowana w sposób szczególny przez kompilator). Tak stworzona klasa Array sprawia, że ze składniowego punktu widzenia jest większa spójność, ale zaglądając do implementacji i tak wracamy do punktu wyjścia.

Z punktu widzenia składniowego ta klasa Array istnieje w jednym egzemplarzu, ponieważ jest parametryzowana typami elementów. Jak wiadomo, generyki są po to, by nie pisać osobno klasy dla każdego typu. Stąd tylko jedna klasa Array w Scali.

0

Ja się na tym nie znam jeszcze, ale byłem dziś w empiku i przeglądając jedną książkę było napisane, że tablice mają coś wspólnego z klasą główną Object. Nie pamiętam czy coś tam dziedziczą, czy coś innego robią, ale jakoś z tą klasą są powiązane.

1
golec2604 napisał(a):

W pewnym momencie doczytałem że tablica też jest obiektem i tyle było na ten temat. Tylko zastanowiło mnie jakiej klasy tablica jest obiektem?

Nie jest żadnej klasy. Nie każdy obiekt musi mieć klasę. Zacytuję:

Dodatkowo, żeby cię upewnić, że tablice nie są żadnej klasy, ale jednak są obiektami, to zamieszczam cytaty:

Ale uwaga! Znalazłem przed chwilą to. Przeczytaj uważnie w tym linku punkt 10.8.:
Zacytuję: "Although an array type is not a class, the Class object of every array acts as if:

  • The direct superclass of every array type is Object.
  • Every array type implements the interfaces Cloneable and java.io.Serializable."

================

golec2604 napisał(a):

Skoro tablica zawiera same tylko referencje do obiektów to tablica nie jest obiektem klasy Abc bo jak by była obiektem klasy Abc to musiała by zawierać takie same pola metody idt jak obiekt tej klasy,

Dokładnie, gdyby była, to tak. :)

golec2604 napisał(a):

Dodatkowo powiem że w moim kodzie wywołanie metody getClass() na tablicy dało taki wynik:
class [Linheritance.Employee; - którego nie rozumiem co on zwraca.

Jak zostało napisane tu: http://stackoverflow.com/a/6867170, znak [ mówi, że jest to tablica, a dalszy ciąg LnazwaKlasy oznacza typ obiektów, które siedzą w tej tablicy. (inheritance to być może przestrzeń nazw, w której jest ta klasa, nie jestem pewien.)

0

Dzięki wszystkim za informacje. Sporo sie dowiedziałem ale i też pewnych rzeczy nie do końca rozumiem. Pewnie dlatego że jestem jeszcze na wczesnym etapie Javy.
Mniej więcej kumam o co chodzi z tym że tablica jest obiektem. Bardzo zmyliło mnie to że taką tablice tworzy się bardzo podobnie do samego tworzenia obiektu, składnia jest prawie identyczna jak do tworzenia obiektu dochodzą jedynie nawiasy kwadratowe i wyglada to tak jak by tablica była obiektem danej klasy.

========================================================
Mam też prośbę do Was że jak coś tłumaczycie to starajcie sie nie tłumaczyć tych pojeć na przykładach wyprzedzających dane zagadnienie, dlatego że jak wspomniałem wcześniej jestem na wczesnym etapie Javy i raczej nie zrozumie tego a mozliwe że narodzą sie wtedy kolejne niepotrzebne i nie związane z tematem pytania.

Wracam do tej metody getClass

kod był taki:

Employee[] staff = new Employee[3];
System.out.println(staff.getClass());

a wynik taki:

class [Linheritance.Employee;

Wg. twojego wytłumaczenia rozumiem to tak:

class [ - oznacza że jest to klasa tablicowa
L - ?? ** (Tylko tego L nie rozumiem co oznacza.)**
inheritance - to nazwa pakietu w jakim znajduje sie dana klasa w której sam umieściłem ją. Górna czesc kodu package inheritance; miałem nie widoczna a zapomniałem sobie o tym.
Employee - nazwa typu do jakich referencji obiektów tablica bedzie przechowywać.

Dobrze rozumiem??? (i na to L poproszę odpowiedź.)

0
golec2604 napisał(a):

Wg. twojego wytłumaczenia rozumiem to tak:

class [ - oznacza że jest to klasa tablicowa
L - ?? ** (Tylko tego L nie rozumiem co oznacza.)**

Nie, to nie jest "klasa tablicowa".
Z tego, co ja rozumiem z dokumentacji, to jest tak: getClass() tworzy ci EDIT: instancję klasy Class, wtedy jest to tzw. class of arrays, która zawiera jako pole twoją tablicę staff. (mogę się mylić, nie znam się aż tak na Javie!) Na tej nowej klasie, z uwagi na to, że wypisujesz do konsoli, zapewne jest wywoływana metoda toString(), która zwraca właśnie ciąg class [Linheritance.Employee. class oznacza tutaj tę nową klasę, a nie tablicę staff.

Gdybyś oprócz getClass() wywołał metodę getName() lub o wiele lepiej getTypeName() (to znaczy: getClass().getName()), to zobaczyłbyś różnicę. Zobacz tutaj, przygotowałem przykład: http://ideone.com/zOGXOx.

0

@Michał Bodziony

Trochę inaczej:
getClass() nie tworzy "nowej klasy", tylko tworzy instancję (obiekt) klasy Class, który zawiera pola i metody przechowujące i wyświetlające informacje o obiekcie, na którym tą metodę wywołano.

0

W książce która przerabiam natrafiłem do pewnego momentu (który na razie nie był omówiony w tej książce) a który był tutaj pokazany ale nie pytałem o to. Tzn.

getClass().getName()

Każda klas dziedziczy po klasie Object. W klasie Object nie ma metody getName().
Dlaczego ta metoda działa z połaczeniu z metoda getClass() skoro jej nie ma w klasie bazowej Objekt a samodzielnie nie działa?
Np.

Date v = new Date();
v.getName()                               // samodzielnie nie działa
v.getClass().getName()                // razem z inna metodą działa
v.getClass()                                // sama metoda getClass() działa (bo jest odziedziczona po Object)
0

Generalnie mam wrażenie, że sam nie wiesz o co pytasz.

Wywołanie:

new Object().getName()

jak już wiesz, nie może działać, bo klasa Object nie posiada metody getName()!!

Dokumentacja klasy Object http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html i klasy Class http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html.
Dodatkowo dokumentacja java.util.Date: http://docs.oracle.com/javase/7/docs/api/java/util/Date.html

Jeśli spojrzysz na deklarację klasy Date:

public class Date extends Object

To będziesz wiedział już, że obiekt klasy date nie może posiadać metody getName() której nie posiada klasa Object a którą to posiada klasa Class.
Dlatego też musisz użyć takiej konstrukcji

jakisObiekt.getClass().getName()

Czy teraz już rozumiesz?

0

NoZI chyba nie zrozumiałeś mojego pytania.
Pytam dlaczego metoda getName() działa w połączeniu z inna metodą skoro ani klasa Date ani Objekt nie posiadają metody getName() ??

0

Zostaw programowanie w spokoju.

Date v = new Date(); //v jest typu Date, w klasie Date nie ma metody getName()
v.getClass() //jest typu Class, w tej klasie jest metoda getName()
0

Ponieważ getName() wywołujemy "z metodą" getClass(), a ta metoda zwraca już obiekt klasy Class, który to posiada metodę getName().

1 użytkowników online, w tym zalogowanych: 0, gości: 1