2011-07-03 10 views
8

Kiedy zainicjować tablicę w Javie lubię:Czy bufory bezpośrednie w języku Java zostały zainicjowane na wartość domyślną, na przykład tablice?

float[] array = new float[1000]; 

wszystkie elementy są inicjowane do 0. Czy to także przypadku, gdy przeznaczyć bezpośredni bufor tak:

FloatBuffer buffer = ByteBuffer.allocateDirect(4*1000).asFloatBuffer(); 

? Zawsze wydaje mi się, że dostaję tylko zera, ale być może zależy to od implementacji ...

+2

Interesujące pytanie. [ByteBuffer javadoc] (http://download.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html) najwyraźniej nic nie mówi w tej sprawie. Zauważ jednak, że przypadki są nieco inne. W pierwszym przypadku każdy element jest inicjalizowany do '0.0f', podczas gdy każdy z odczytów zmiennoprzecinkowych o wartości' 0.0f' będzie spowodowany faktem, że [* wzorzec bitowy * dla '0.0f' to" wszystkie zera "] (http://steve.hollasch.net/cgindex/coding/ieeefloat.html) w IEEE-754 –

+0

Zobacz moją odpowiedź poniżej: javadoc ByteBuffer nic nie mówi, ale rodzicielska klasa Buffer ma. –

Odpowiedz

3

Z ducmentation do macierzystej klasy abstrakcyjnej Bufor

Początkowa zawartość bufora jest, na ogół, nieokreślone.

W przypadku braku czegokolwiek innego, zakładam, że odnosi się to do buforów przydzielonych przez ByteBuffer.allocateDirect(). Co ciekawe, przypuszczam, że ściśle dotyczy to również zwykłych buforów z tablicami, choć jest to nieodłączne w przydziale tablicy Javy, że tablica zostanie wyzerowana.

+0

Jestem pewien, że ta odpowiedź była poprawna, kiedy ją opublikowałeś, ale już nią nie jest. –

+0

Myślę, że to było poprawne w tym czasie, ale jak mówisz, wygląda na to, że zostało to wyjaśnione w ostatnich JDKs i można założyć, że bezpośrednie bufory są wyzerowane. –

4

Wygląda na to, że odpowiedź brzmi: prawdopodobnie.

Patrząc na realizację ByteBuffer, używa pod maską DirectByteBuffer. Przyjrzeniu realizacji source code Androida, ma ten komentarz:

konstruuje nowy bezpośredni bufor bajtów danej pojemności na nowo przydzielonej pamięci OS. Pamięć zostanie wyzerowana na .

Po przydzieleniu bufora cała zawartość pamięci zostanie zainicjowana na zero. Implementacja Oracle dokonuje również zerowania.

Jest to jednak szczegół implementacji. Ponieważ javadoc nie mówi nic o zerowaniu, technicznie niepoprawne jest poleganie na nim. Aby być poprawnym, należy samemu zerować bufor. W praktyce, jeśli z jakiegoś powodu naprawdę martwisz się wydajnością, możesz go pominąć, ale pamiętaj, że niektóre implementacje maszyny JVM mogą tego nie robić.

+2

Nie zgadzam się: komentarz jest tylko komentarzem do implementacji, a nie komentarzem javadoc. I to tylko w implementacji Androida. Kod źródłowy implementacji Oracle nie zawiera tego komentarza, chociaż ustawia także pamięć na 0. Więc moja odpowiedź byłaby taka, że ​​prawdopodobnie zawsze jest wyzerowana, ale nie możesz być tego pewien. –

+0

Zaktualizowałem moją odpowiedź, aby było jasne, że jest to szczegół implementacji. Dzięki @ jb-nizet – jterrace

+0

Zobacz moją odpowiedź poniżej: jest nieco ukryty, ale javadoc faktycznie oznacza, że ​​NIE można polegać na tym, że bufor został wyzerowany. –

0

Nie ma sposobu, aby powiedzieć, więc pytanie jest daremne. Początkowa pozycja wynosi zero, więc nie można uruchomić interfejsu API, który zwróci część bufora, która nie została jeszcze "dodana".

+0

Co z plikiem buffer.get (indeks int)? Mogę zrobić: FloatBuffer buf = ByteBuffer.allocateDirect (400) .asFloatBuffer(); System.out.println (buf.get (7)); która wyprowadza 0.0 –

+0

Z pewnością zgłasza wyjątek niedopełnienia, jeśli nic tam nie ma? – EJP

+0

to nie dla mnie, według mojej wiedzy indeks jest sprawdzany tylko względem limitu buforów. Wyjątek niedopełnienia jest wyświetlany tylko w przypadku użycia metody dostępu względnego i przekroczenia limitu. Absolute get (jak w get (int index) zgłasza wyjątek poza limitem, ale tylko jeśli indeks> limit –

1

Patrząc na Javadoc dla Java 7 a także Java 8

teraz mówi

Stanowisko nowy bufor będzie zerowy, jego granica będzie jej zdolność , jego znak będzie niezdefiniowana, a każdy jego elementów będzie zainicjalizowany do zera. Niezależnie od tego, czy ma on tablicę zabezpieczającą, czy nie, nieokreślono:

Nie ma już potrzeby samodzielnego zerowania.