Perché non c'è alcuna funzione costante in Java?


140

Stavo cercando di identificare il motivo dietro le costanti in Java. Ho imparato che Java ci consente di dichiarare le costanti usando la finalparola chiave.

La mia domanda è: perché Java non ha introdotto una funzione Constant ( const). Poiché molte persone affermano che proviene dal C ++, in C ++ abbiamo una constparola chiave.

Per favore, condividi i tuoi pensieri.


2
V'è una constparola chiave, ma non v'è alcuna funzionalità di base. Corretto il titolo e i tag di conseguenza.
Marchese di Lorne,

Risposte:


142

Ogni volta che passo dalla pesante codifica C ++ a Java, mi ci vuole un po 'di tempo per adattarmi alla mancanza di correttezza const in Java. Questo utilizzo di constin C ++ è molto diverso dalla semplice dichiarazione di variabili costanti, se non lo sapevi. In sostanza, assicura che un oggetto sia immutabile quando vi si accede tramite un tipo speciale di puntatore chiamato const-pointer. Quando in Java, in luoghi in cui normalmente vorrei restituire un const-pointer, restituisco invece un riferimento con un tipo di interfaccia contenente solo metodi che non dovrebbero avere effetti collaterali. Sfortunatamente, questo non è imposto dalla lingua.

Wikipedia offre le seguenti informazioni sull'argomento:

È interessante notare che le specifiche del linguaggio Java considerano const una parola chiave riservata, ovvero una parola che non può essere utilizzata come identificatore di variabile, ma che non assegna ad essa alcuna semantica. Si ritiene che la prenotazione della parola chiave si sia verificata per consentire a un'estensione del linguaggio Java di includere i metodi const in stile C ++ e il puntatore al tipo const. Il ticket di richiesta di miglioramento nel Java Community Process per l'implementazione della correttezza const in Java è stato chiuso nel 2005, il che implica che la correttezza const probabilmente non troverà mai la sua strada nelle specifiche ufficiali Java.


10
Java finalè simile, però.
reinierpost,

62
No non lo è. finalil metodo, ad esempio, funziona in modo completamente diverso dai constmetodi C ++ .
dom0

7
@reinierpost La finalparola chiave su proprietà o variabili assicura solo che una proprietà o variabile venga assegnata una sola volta . Si potrebbe ancora alterare lo stato di questo oggetto, ad esempio chiamando un metodo con effetti collaterali. finalè in qualche modo simile impilare l'allocazione di C ++ in termini di riferimento a un oggetto piuttosto che a un puntatore, ma questo è tutto. Questo è ovvio in aggiunta a quanto già detto dom0.
Tim

9
finalin Java sembra funzionare come C ++ constper i tipi di valore, ma più come una C ++ non const T&per i tipi di riferimento
Mark K Cowan,

1
final è una parola chiave schizofrenica. Mentre impedisce la riassegnazione, viene anche utilizzato per esporre le variabili alle chiusure. Potrei voler impedire la riassegnazione ma non esporre quelle variabili, ma non c'è modo di farlo. Secondo me, è una caratteristica linguistica piuttosto mal pensata.
David Bradley,

82

Cosa constsignifica
Innanzitutto, rendersi conto che la semantica di una parola chiave "const" significa cose diverse per persone diverse:

  • riferimento di sola lettura - finalsemantica Java - la variabile di riferimento stessa non può essere riassegnata per puntare a un'altra istanza (posizione della memoria), ma l'istanza stessa è modificabile
  • riferimento di sola lettura - constpuntatore C / semantica di riferimento - indica che questo riferimento non può essere utilizzato per modificare l'istanza (ad es. impossibile assegnare a variabili di istanza, non può invocare metodi mutabili) - influisce solo sulla variabile di riferimento, quindi un riferimento non const che punta al stessa istanza potrebbe modificare l'istanza
  • oggetto immutabile - significa che l'istanza stessa non può essere modificata - si applica all'istanza, quindi qualsiasi riferimento non const non sarebbe consentito o non potrebbe essere utilizzato per modificare l'istanza
  • una combinazione di quanto sopra ?
  • altri ?

Why or Why Notconst
Second, se vuoi davvero approfondire alcuni degli argomenti "pro" vs "con", vedi la discussione sotto questo "bug" di richiesta di miglioramento (RFE). Questo RFE richiede una funzione "const" di tipo "riferimento di sola lettura". Inaugurato nel 1999 e poi chiuso / respinto da Sun nel 2005, l'argomento "const" è stato fortemente dibattuto:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4211070

Mentre ci sono molti buoni argomenti da entrambe le parti, alcuni dei motivi spesso citati (ma non necessariamente convincenti o chiari) constsono:

  • potrebbe avere una semantica confusa che potrebbe essere utilizzata in modo improprio e / o abusato (vedere Cosa constsignifica sopra)
  • può duplicare funzionalità altrimenti disponibili (ad es. progettare una classe immutabile, usando un'interfaccia immutabile)
  • può essere un creep di funzionalità, che porta alla necessità di altre modifiche semantiche come il supporto per il passaggio di oggetti in base al valore

Prima che qualcuno cerchi di discutermi se queste sono ragioni buone o cattive, nota che queste non sono le mie ragioni . Sono semplicemente il "nocciolo" di alcuni dei motivi che ho raccolto dalla discussione sulla RFE. Non sono necessariamente d'accordo con loro, sto semplicemente cercando di citare perché alcune persone (non io) potrebbero ritenere che una constparola chiave potrebbe non essere una buona idea. Personalmente, mi piacerebbe che più semantica "const" venisse introdotta nella lingua in modo inequivocabile.


2
+1 solo per la seconda parte della tua risposta. Molte molte parole chiave hanno una semantica non banale. È volatilecosì semplice da capire? Oppure final? Meh.
einpoklum,

OTOH, Java è stato progettato per utilizzare il minor numero possibile di funzionalità non banali. E non sto dicendo che abbiano raggiunto quell'obiettivo (o che Java non si sia allontanato da quell'obiettivo). Ma escluderlo per questo motivo potrebbe aver avuto ancora dei meriti. Che ci siano altre cose complicate è una ragione in più per non introdurre altro (o finiresti con il linguaggio D).
Maarten Bodewes,

7

const in C ++ non significa che un valore è una costante.

const in C ++ implica che il cliente di un contratto si impegna a non alterarne il valore.

Se il valore di constun'espressione cambia diventa più evidente se ci si trova in un ambiente che supporta la concorrenza basata su thread.

Poiché Java è stato progettato fin dall'inizio per supportare il thread e bloccare la concorrenza, non ha aggiunto confusione sovraccaricando il termine per avere la semantica che final ha.

per esempio:

#include <iostream>

int main ()
{
    volatile const int x = 42;

    std::cout << x << std::endl;

    *const_cast<int*>(&x) = 7;

    std::cout << x << std::endl;

    return 0;
}

uscite 42 quindi 7.

Sebbene xcontrassegnato come const, quando viene creato un alias non const, xnon è una costante. Non tutti i compilatori richiedonovolatile questo comportamento (sebbene a ogni compilatore sia consentito di incorporare la costante)

Con i sistemi più complicati ottieni alias const / non-const senza l'uso di const_cast, quindi prendere l'abitudine di pensare che const significhi che qualcosa non cambierà diventa sempre più pericoloso. constsignifica semplicemente che il tuo codice non può cambiarlo senza un cast, non che il valore è costante.


3
const int x = 42; - x è una costante

2
@Neil Se si dispone di un oggetto o di una variabile con alias sia da puntatori const che non const, il valore dell'alias const può essere modificato dall'alias non const. Pertanto constnon significa che un valore sia costante. Significa che il client di un valore è costretto a non modificarlo. Nel tuo esempio non esiste un alias, quindi tutti gli utenti hanno lo stesso vincolo. Questo non è il caso in generale. constincide sui client, non sul valore - dice che non puoi cambiarlo, non che non cambierà.
Pete Kirkham,

1
La costanza corretta riguarda ciò che il programmatore dovrebbe fare, non ciò che può fare . Penso che tutti voi abbiate capito quel punto. Volevo solo aggiungere un paio di centesimi che potrebbero interessare il lettore causale: progettare modelli come the immutable interfaceed immutable objectè un altro modo (battibile con cast e riflessione) per imitare const in Java. La const "True" può essere eseguita con SealedObject , purtroppo distrugge il caso d'uso del nostro oggetto.
Martin Andersson,

6
Si noti che il risultato del programma non è definito. const_cast non è lì per modificare le variabili const, è lì per passare le variabili const alle API che non sono corrette, ma non modificano il valore. Penso che l'abitudine di pensare che qualcosa di const non cambierà è una buona cosa perché se cambiano, ciò significa che il tuo programma contiene hack che potrebbero rompersi in qualsiasi momento a seconda del compilatore utilizzato.
Cygon

1
La modifica di un valore nato per costante è un comportamento indefinito. Il tuo disco potrebbe essere già formattato.
Zhe Yang,

5

Questa è una domanda un po 'vecchia, ma ho pensato di contribuire comunque con i miei 2 centesimi da quando questa discussione è venuta in discussione oggi.

Questo non risponde esattamente perché non c'è const? ma come rendere immutabili le tue lezioni. (Purtroppo non ho ancora abbastanza reputazione per pubblicare come commento la risposta accettata)

Il modo per garantire l'immutabilità su un oggetto è progettare le tue classi con più attenzione per renderle immutabili. Ciò richiede un po 'più di cura di una classe mutevole.

Questo risale all'Efficace Java Item di Josh Bloch 15 - Ridurre al minimo la mutabilità . Se non hai letto il libro, prendine una copia e leggilo più volte, ti garantisco che migliorerà il tuo "gioco java" figurativo .

Nell'elemento 15 Bloch suggerisce di limitare la mutabilità delle classi per garantire lo stato dell'oggetto.

Per citare direttamente il libro:

Una classe immutabile è semplicemente una classe le cui istanze non possono essere modificate. Tutte le informazioni contenute in ciascuna istanza vengono fornite al momento della creazione e sono fisse per la durata dell'oggetto. Le librerie della piattaforma Java contengono molte classi immutabili, tra cui String, le classi primitive in box e BigInteger e BigDecimal. Ci sono molte buone ragioni per questo: le classi immutabili sono più facili da progettare, implementare e usare rispetto alle classi mutabili. Sono meno soggetti a errori e sono più sicuri.

Bloch quindi descrive come rendere immutabili le tue classi, seguendo 5 semplici regole:

  1. Non fornire alcun metodo che modifichi lo stato dell'oggetto (es. Setter, aka mutatori )
  2. Assicurarsi che la classe non possa essere estesa (questo significa dichiarare la classe stessa come final).
  3. Crea tutti i campi final.
  4. Crea tutti i campi private.
  5. Garantire l'accesso esclusivo a tutti i componenti mutabili. (facendo copie difensive degli oggetti)

Per maggiori dettagli, consiglio vivamente di ritirare una copia del libro.


3
const in C ++ è MOLTO più flessibile dell'immutabilità su vasta scala. In un certo senso, "const" può essere visto come "immutabile in questo particolare contesto". Esempio: ho una classe che non è immutabile, MA voglio assicurarmi che non venga modificata tramite determinate API pubbliche. Creare un'interfaccia (e restituirla per quell'API pubblica) come suggerito da Gunslinger47 ottiene la stessa cosa in Java, ma ragazzo - È brutto (e così - viene ignorato dalla maggior parte degli sviluppatori Java, portando a un significativo disordine inutile) .. .
No-Bugs Hare

3

La semantica C ++ di constè molto diversa da Java final. Se i designer avessero usatoconst , sarebbe stato inutilmente confuso.

Il fatto che constsia una parola riservata suggerisce che i progettisti avevano idee per l'implementazione const, ma da allora hanno deciso di non farlo; vedi questo bug chiuso . Le ragioni dichiarate includono che l'aggiunta del supporto per lo stile C ++ constcauserebbe problemi di compatibilità.


-1

C'è un modo per creare variabili "const" in Java, ma solo per classi specifiche. Basta definire una classe con le proprietà finali e sottoclassarla. Quindi utilizzare la classe di base in cui si desidera utilizzare "const". Allo stesso modo, se è necessario utilizzare metodi "const", aggiungerli alla classe base. Il compilatore non ti consentirà di modificare quelli che ritiene siano i metodi finali della classe base, ma leggerà e chiamerà i metodi nella sottoclasse.


Puoi fornire qualche esempio di questo, per favore?
NO_NAME

class MYString implementa GetString {private final String aaaa; public String getString (); } class MutableString implementa GetString {private String aaaa2; public String getString (); public String setString ()}
user1122069

-2

Ci sarebbero due modi per definire le costanti - conste static final, con la stessa identica semantica. Inoltre static finaldescrive il comportamento meglio diconst


@ Bozho, hai detto un comportamento migliore di Const, in che modo? puoi condividere qualche esempio
gmhk

bene, la variabile è static(non appartenente a un'istanza particolare) e final- non può essere cambiata.
Bozho,

-2

Puoi usare il finale statico per creare qualcosa che funzioni in modo simile a Const, l'ho usato in passato.

protected static final int cOTHER = 0;
protected static final int cRPM = 1;
protected static final int cSPEED = 2;
protected static final int cTPS = 3;
protected int DataItemEnum = 0;

public static final int INVALID_PIN = -1;
public static final int LED_PIN = 0;

Sottovalutato per ottimizzazione basata sulle voci perché ho sentito dire che si tratta di una strategia inefficace.
lontano

Ho rimosso la voce dalla risposta. puoi ancora usare int finale statico per creare il codice di stile const.
hamish

Ok, ho rimosso il mio voto negativo. Forse alcuni degli altri downvotes riguardano l'istruzione switch (cosa ha a che fare con il resto del tuo esempio?)
afarley

nell'istruzione switch ho usato cRPM come se fosse una const. assolutamente giusto, considerando quanto sopra. quindi sì, ho rimosso l'interruttore.
hamish
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.