2013-03-01 11 views
8

Sto rivedendo la guida allo studio della certificazione Sun e c'è un passaggio che descrive il modificatore finale. Si diceEreditarietà Java, in che modo l'estensione di una classe influisce sulla classe effettiva

"Se i programmatori erano liberi di estendere la civiltà classe String come lo conosciamo potrebbe crollare"

Che cosa vuol dire? Se fosse possibile estendere la Classe Stringa ... non avrei semplicemente una classe chiamata MyString che eredita tutte le proprietà delle Stringhe. Come sarebbe possibile modificare la classe String effettiva in qualche modo solo estendendola?

La ringrazio molto per le vostre risposte

+2

suona un po 'iperbolico – mre

+0

@mre sì, ma incredibilmente così dato che è nell'esame di certificazione! – sharakan

+2

@drlobo Penso che dovresti cambiare il titolo di questa domanda in: "Perché la guida allo studio della certificazione Sun pensa che estendere la classe String causerà il collasso della civiltà?" – sharakan

risposta

4

estensione di una classe non influisce sulla classe base. Tuttavia, potrebbe influire sui consumatori della classe base.

Quindi, diciamo che si stati in grado di estendere String, si potrebbe scrivere qualcosa di simile a quanto segue:

class MyString extends String { 

    @Override 
    public int length() { 
     System.exit(); 
    } 
} 

Ora si passa questa classe a qualsiasi cosa che utilizza una stringa, e le probabilità sono che si uscire rapidamente dal programma. Non la fine della civiltà, ma ci sono cose un po 'più sinistre che potresti fare.

6

Bene, un problema è che molto probabilmente si può sovvertire la sicurezza di jvm in una miriade di modi se è possibile sottoclasse la classe String. Molte delle autorizzazioni verificano vari valori di stringa per determinare se è consentita o meno una determinata azione. se il codice fornisce i valori stringa, è possibile restituire un'istanza String che "estrapola" quando il gestore della sicurezza lo esamina, ma in seguito si comporta come un valore completamente diverso.

esempio, supponiamo di avere un po 'sensibile a livello di JVM configurazione:

public static void registerProvider(String providerName, Provider impl) { 
    SecurityManager sm = ...; 
    if(sm != null) { 
    // say the check provider method doesn't allow strings starting with "com.sun." 
    sm.checkProvider(providerName); 
    } 
    _providerMap.put(providerName, impl); 
} 

Ora, implemento una stringa personalizzata che sostituisce il metodo startsWith() per restituire false se superato il valore "com.sun.", ma il valore effettivo della mia La stringa inizia con com.sun..

Per non parlare, naturalmente, dell'aspettativa generale che le stringhe siano immutabili e che, se interrotte, potrebbero causare tutti i tipi di caos generale (come menzionato più dettagliatamente in altre risposte).

+0

Chiameresti questo 'ChuckNorrisString'? :-) – kdgregory

+0

Sebbene, a mio avviso, 'ChuckNorrisString' sovrascriva' hashCode() ': lo metti in una mappa e quando torni indietro per cercarlo, non è lì. – kdgregory

+0

@kdgregory - un ChuckNorrisString non sarebbe molto utile perché non sarebbe mai uguale a nulla. e ordinarlo sarebbe difficile perché sarebbe sempre più grande di ogni altra cosa. – jtahlborn

2

Si consideri che in tutto l'API Java, si vedrà costrutti quali:

HashMap<String, Object> map; 

che utilizzano le stringhe per l'indicizzazione. Una cosa molto comune, ad es. per le proprietà e - e che probabilmente è il peggiore in posti rilevanti per la sicurezza. Questo codice si basa su un String non modificato per rimanere al sicuro.

Ma ora consenti la classe String modificata ad es. Invertire le stringhe sul posto.

Quindi il mondo come lo conosciamo crollerebbe, perché in tutto il luogo le mappe diventerebbero un pasticcio pazzo. La registrazione si interromperà, ecc.

un sacco di codice si basa sulla classe String essere immutabili, e bene, se è veramente immutabile, quali funzionalità potrebbe che si desidera aggiungere ad esso comunque?

+0

La modifica del comportamento non deve invalidare un vincolo di immutabilità. Pensa a una classe 'ReversedString' con un comodo costruttore. –

+0

@jeppi si potrebbe fare questo fuori luogo banalmente con un metodo statico, senza la necessità di una nuova classe affatto, in realtà. –

+0

In scenari somi si preferiscono i costruttori rispetto ai metodi di produzione statici. Forse ReversedString non è l'esempio più realistico per questo. Era lì solo per parlare di oggetti immutabili ... –

1

L'estensione di una classe non ha alcun effetto sulla classe. tuttavia, poiché ogni classe ereditata è anche una classe base, dovrebbe rispettare i contratti di comportamento della classe base. se i programmatori dovessero cambiare i tipi di framework comuni, allora non potreste contare su quelle classi per funzionare come previsto. Pertanto, si desidera impedire l'utilizzo di tali classi utilizzando la parola chiave

0

L'iperbole della catastrofe è probabilmente un'allusione agli aspetti di sicurezza della mutabilità di String (im). Una stringa viene spesso passata come parametro a varie API di connessione di risorse di I/O (ad esempio JDBC e I/O di file). Tale stringa se spesso una concatenazione di localizzatori di risorse e credenziali di autenticazione e quell'API eseguiranno un controllo per assicurarsi che le credenziali siano valide per la risorsa richiesta prima di restituire la connessione. Se String fosse mutabile, aprirà il gateway per tutti i tipi di violazioni della sicurezza come il puntatore/indirizzo della risorsa (come ad esempio un nome di database per la connessione DB o il nome del file contenente informazioni sensibili per un utente) potrebbe essere modificato dopo il l'autenticazione ha avuto esito positivo ma prima che venga stabilita la connessione della risorsa per la risorsa originale richiesta, con conseguente accesso non autorizzato e controllo di accesso sovvertito.

Un altro motivo per rendere String immutabile è renderlo thread-safe.

0

In realtà il problema non ha nulla a che vedere con l'estensione di String o qualsiasi altra classe.

Il problema è in realtà con Java stesso. Il problema è che non puoi effettivamente definire nel suo codice il contratto che un particolare oggetto implementa. Non è in realtà indicato nel codice per String che è immutabile perché non è possibile specificare l'immutabilità, può solo essere codificata. Tale contratto nasce solo dall'attuazione effettiva di String.

se fosse possibile affermare in linguaggio Java che String e Number e Integer ecc sono immutabili, allora non ci sarebbe bisogno di fare queste classi final. Secondo me questa è una malattia debilitante di Java che non è possibile definire il contratto nel codice. Puoi solo codificarlo e documentarlo.

Mi piacerebbe essere in grado di estendere stringa e definire, forse, un UppercaseString extends String ma non c'è una parola chiave contract(immutable,interned) in Java, quindi non posso farlo perché per arrivare più vicino al presente contratto, l'unica parola chiave disponibile è final invece di immutable come dovrebbe essere.

Problemi correlati