Java ha dei puntatori?

Se Java non ha puntatori, cosa fa la new parola chiave in Java?

Come sottolineato, Java ha riferimenti. Come sono questi diversi?

  1. su questi non è ansible eseguire operazioni aritmetiche o simili
  2. non puntano alla memoria contenente l’object (cioè non sono puntatori di un altro nome). La JVM è libera di spostare oggetti all’interno della memoria della VM e molto probabilmente lo farà durante la garbage collection. I riferimenti comunque indicano ancora quell’object, nonostante il suo movimento nella memoria.

Quindi non sono come riferimenti C ++ (che puntano direttamente a un object). Forse un nome migliore sarebbe gestibile .

Java non ha puntatori; Java ha riferimenti.

È un punto sottile, ma un puntatore ha operazioni extra che puoi (o non puoi) usare in genere; un riferimento manca di queste operazioni perché le operazioni potrebbero essere non sicure.

Ad esempio, se si utilizza un puntatore per indicizzare il primo elemento di un array in questo modo:

 int squares[] = {1, 4, 9, 16, 25, 36, 49}; int* intPointer = squares; 

potresti voler dereferenziare il puntatore e ottenere il valore “1”, ma puoi anche:

 intPointer++ 

e dopo averlo fatto, quando si dereferenzia il puntatore si otterrà il valore “4”. Un secondo

 intPointer++; 

sarà, quando dereferenziato, darti il ​​valore “9”. Questo perché l’operazione ++ sposta il puntatore di una “unità” in memoria.

Il problema deriva dai punti deboli del sistema di tipizzazione C / C ++ (C ++ deve mantenere la compatibilità con C, quindi consente gli stessi problemi). Il puntatore memorizza un indirizzo in memoria e l’operazione ++ aggiunge il numero appropriato di byte all’indirizzo. Su molti sistemi ++ e un int aggiunge quattro byte, ma se il puntatore era un puntatore di char ++ lo dovrebbe aggiungere solo un byte. Si noti che poiché il tipo di dati sottostante di un puntatore è un indirizzo in memoria, quanto segue è legale (ma non consigliato):

 char* charPointer = squares; charPointer++; void* voidPointer = squares; voidPointer++; 

Dato che i puntatori sono indirizzi in memoria, potrebbero rappresentare (correttamente) qualsiasi bit di memoria nel computer, ma sono solo deferiti correttamente quando i dati sottostanti determinano il tipo e l’allineamento del puntatore. Per i puntatori che non sono gestiti da un sacco di codice per renderli sicuri, ciò significa che si potrebbe sviare il tipo di dati (o l’allineamento) delle informazioni desiderate e una dereferenza potrebbe finire in caso di disastro. Il tentativo di risolvere questo problema con il codice personalizzato tende a rallentare un puntatore in modo abbastanza grave da notare problemi di prestazioni e apre le porte per l’aggiunta di errori nel codice personalizzato “gestione puntatore”.

Java spiega tutti questi problemi restituendo un riferimento. Un riferimento non si riferisce a nessuna posizione nella memoria; Java mantiene una tabella interna “riferimento al puntatore”. Questa tabella prende il riferimento e restituisce i dati ad esso associati, dovunque i dati possano risiedere nella memoria. Questo rallenta l’esecuzione del codice, poiché vengono eseguite due ricerche per ogni “dereferenziazione”, una ricerca nella tabella di riferimento, una nella memoria della macchina.

Un grande vantaggio di Java che utilizza i riferimenti è che la memoria può essere spostata senza rompere gli indirizzi dei puntatori. In un programma C, se si spostano i dati in una nuova posizione di memoria, è molto difficile sapere se un’altra parte del programma ha un puntatore ai dati. Se un puntatore non aggiornato viene dereferenziato dopo che la memoria è stata spostata, il programma accederà a dati corrotti e, in genere, si verificherà un arresto anomalo.

La possibilità di spostare la memoria in un programma in esecuzione consente ai programmi di riciclare facilmente la memoria. Qualsiasi programma che non ha bisogno di pezzi di memoria può rilasciare la memoria non utilizzata, ma crea buchi di memoria di memoria inutilizzata tra blocchi di memoria utilizzata. I computer interni utilizzano pagine di memoria, che sono piuttosto grandi. Se una pagina di memoria scarsamente usata può far spostare i pochi bit utilizzati in un’altra pagina, è ansible liberare una pagina di memoria. Ciò aumenta la densità dei dati nella memoria, migliorando le prestazioni della cache. A volte questo si traduce in miglioramenti delle prestazioni che possono essere piuttosto drammatici.

Java’s Garbage Collector sfrutta l’utilizzo di riferimenti bloccando temporaneamente l’accesso ai dati per un insieme di riferimenti. Durante quel blocco di accesso, sposta i dati attorno (per compattarlo). Dopo il blocco, il riferimento alla tabella degli indirizzi ha i nuovi indirizzi di memoria. Poiché il livello “funzionale” del codice non ha mai conosciuto gli indirizzi in primo luogo, questa operazione non interromperà un programma Java in esecuzione.

Java ha dei puntatori nel senso di variabili che memorizzano riferimenti a dati in memoria. Tutte le variabili dei tipi di object in Java sono indicatori in questo senso.

Tuttavia, il linguaggio Java non consente operazioni aritmetiche sui valori dei puntatori, come si sarebbe in grado di fare in una lingua come C.

new fa (all’incirca) il seguente:

  1. Trova un blocco libero contiguo di memoria heap uguale alla dimensione dell’istanza della class che stai creando, oltre a un po ‘di spazio per la contabilità
  2. Zero ha detto spazio e rimuoverlo dalla lista libera
  3. Esegui il costruttore
  4. Restituisce un riferimento (NON un puntatore, come hanno spiegato altri post) all’istanza creata.

java.lang.NullPointerException

La gente mi ha detto “che java non ha punti” nelle interviste. Di solito davo loro del codice java e lasciavo che spiegassero cosa sta succedendo in questo codice:

 public class TestPointers { public static void main(String args[]) { Object p1, p2; p1 = new Object(); p2 = p1; p1 = null; System.out.println(p2); } } 

Java ha riferimenti. Si accede a tutti gli oggetti attraverso i riferimenti alle loro istanze. Si crea una nuova istanza usando new , che restituisce un riferimento all’object.

I riferimenti Java non sono come i puntatori in C, non puoi “guardare sotto il cofano” nella memoria grezza che compone l’object.

Java non ha puntatori. L’operatore “nuovo” è utilizzato per la variabile di riferimento in java.

new in Java restituisce un riferimento all’object appena creato.

nuovo riferimento di resi. ha alcune somiglianze con i puntatori (se passi alla funzione, il riferimento è passato, come con il puntatore), ma non c’è aritmetica puntatore.

Java non supporta o non consente puntatori. (O più correttamente, Java non supporta i puntatori a cui è ansible accedere e / o modificare dal programmatore.) Java non può consentire i puntatori, perché così facendo consentirebbe alle applet Java di violare il firewall tra l’ambiente di esecuzione Java e il computer host. (Ricordare che a un puntatore può essere assegnato qualsiasi indirizzo in memoria, anche gli indirizzi che potrebbero trovarsi al di fuori del sistema di runtime Java).

Java ha dei puntatori, che sono noti sotto il nome di ” riferimento “.

Quando la gente dice “Java non ha puntatori”, in genere confondono il concetto di un puntatore con l’implementazione e le abilità specifiche dei puntatori trovati nei linguaggi derivati ​​da C e C.

In particolare:

  • I riferimenti Java non possono essere impostati su un indirizzo arbitrario . Né può (standard) Pascal né i puntatori Fortran.
  • I riferimenti Java non possono essere impostati per puntare a una variabile . Né possono (standard) puntatori Pascal.
  • I riferimenti Java non supportano l’aritmetica del puntatore . Né puntatori Pascal né Fortran
  • I riferimenti Java non possono puntare a parti di un object (come il terzo elemento di un array). Né può i suggerimenti Pascal.

Inoltre, contrariamente a quanto si crede, un puntatore non è necessariamente un indirizzo . Un puntatore viene tipicamente implementato come un indirizzo, ma non è necessario farlo, nemmeno in C o C ++.

In java troviamo solo questo puntatore, è usato per riferirsi alle variabili della stessa class. L’operatore new viene utilizzato come riferimento a un object.