Perché Java ci consente di compilare una classe con un nome diverso dal nome del file?


170

Ho un file Test.javae il seguente codice al suo interno.

public class Abcd
{
        //some code here

}

Ora la classe non si compila, ma quando rimuovo il publicmodificatore, si compila bene.

Qual è il ragionamento alla base di Java che ci consente di compilare un nome di classe diverso dal nome del file quando non è pubblico.

So che è una domanda da principiante, ma non sono in grado di trovare una buona spiegazione.


28
Perché Java. (Perché non è pubblico e non deve seguire la stessa convenzione di denominazione. Oltre a ciò, dovresti chiedere alle persone che l'hanno inventato.)
Dave Newton,

2
Dubito che esista una "buona spiegazione". Era un requisito per le classi pubbliche, ma era ritenuto superfluo per le classi non pubbliche.
Kayaman,

2
Sembra una domanda simile: stackoverflow.com/questions/7633631/…
sanket

4
Perché così tanti voti positivi per questa domanda, prima di tutto la sua duplice domanda: stackoverflow.com/questions/7633631/…
GM Ramesh,

2
@ Ramesh: il titolo e il contenuto di questa domanda è migliore .. (rispetto ad altri simili)
Jayan,

Risposte:


325

La logica è consentire più di una classe di livello superiore per .javafile.

Molte classi, come i listener di eventi, sono solo di uso locale e le prime versioni di Java non supportavano classi nidificate. Senza questo allentamento della regola "nome file = nome classe", ciascuna di queste classi avrebbe richiesto il proprio file, con il risultato inevitabile della proliferazione senza fine di piccoli .javafile e la diffusione di codice strettamente accoppiato.

Non appena Java ha introdotto le classi nidificate, l'importanza di questa regola è diminuita in modo significativo. Oggi puoi passare attraverso molte centinaia di file Java, senza mai incorrere in uno che ne approfitta.


60
+1, questo in realtà fornisce un motivo , che è la domanda.
Dave Newton,

4
+1 in particolare per le informazioni storiche: sospetto che con l'avvento delle classi nidificate / anonime, se la stessa decisione venisse presa ora (senza preoccuparsi della compatibilità con le versioni precedenti), sarebbe molto più logico consentire solo una classe di livello superiore per file.
Michael Berry,

1
@ berry120 Probabilmente, perché questa tolleranza complica la ricerca dei file durante la compilazione.
Marko Topolnik,

3
@Val Negare che altre persone preferiscano utilizzare un editor di testo e strumenti CLI per lo sviluppo perché l'IDE che preferisci esiste è altrettanto sciocco del dire che non ha senso creare IDE perché puoi fare lo sviluppo senza di loro. Entrambi gli approcci sono utilizzati da buoni sviluppatori per creare un codice di qualità; e l'unica cosa più piccola delle probabilità di tutti gli sviluppatori di stabilirne una e cantare kumbaya è la probabilità che saremo tutti d'accordo su quale sia il miglior linguaggio di programmazione.
Dan Fiddling By Firelight,

5
La combinazione di Emacs (o Vim, scegli il tuo veleno) e le utility della shell Unix non sono forse tutto a portata di mano come un IDE moderno, e sono sicuramente più difficili da imparare, ma hanno due vantaggi travolgenti rispetto a ogni IDE che abbia mai provato: non si bloccano mai, non importa quanto sia grande la base di codice, e possono tenere il passo con la mia digitazione.
zwol,

80

Il motivo è lo stesso delle piastre della porta. Se una persona risiede ufficialmente in ufficio (dichiarata pubblica) il suo nome deve essere sull'etichetta della porta. Come "Alex Jones" o "Detective Colombo". Se qualcuno visita la stanza, parla con un funzionario o pulisce il pavimento, il suo nome non deve essere ufficialmente messo sulla porta. Invece, la porta può leggere "Utilità" o "Sala riunioni".

Nome ufficiale o MyClass.java Sala riunioni o Test.java


4
Sicuramente un'analogia interessante; potrebbe essere ancora meglio con un po 'di spiegazione di come si collega direttamente. L'OP potrebbe avere qualche difficoltà a stabilire la connessione (anche se la capisco perfettamente)
Andrew Barber,

4
@AndrewBarber Non penso che l'analogia si adatti davvero perché non modella l'unica classe pubblica, condividendo il file con diverse classi pacchetto-private. È come se la targa della porta avesse scritto "Heather Santee, Manager", ma la stanza in realtà conteneva Heather e i suoi due segretari.
Marko Topolnik,

@MarkoTopolnik Non avrei dovuto essere coinvolto in questo; Sono di classe A orribile con le analogie! ;)
Andrew Barber,

@AndrewBarber Volevo scriverlo, comunque; hai appena dato una spinta :) L'analogia non riesce anche a esprimere la preoccupazione più acuta: proprio per questa caratteristica il compilatore deve analizzare tutti i file per scoprire tutte le classi dove altrimenti potrebbe semplicemente leggere l'elenco delle directory e conoscere i nomi di tutti classi di alto livello.
Marko Topolnik,

@AndrewBarber, l'analogia si adatta perfettamente all'idea di directory, nel lungo corridoio puoi trovare rapidamente una persona semplicemente guardando i piatti della porta, non è necessario entrare in ogni stanza e chiedere.
exebook

29

Le specifiche Java indicano che è possibile avere al massimo solo una classe pubblica per file. In questo caso, il nome della classe deve corrispondere al nome del file. Tutte le classi non pubbliche possono avere qualsiasi nome, indipendentemente dal nome del file.


20
Ma "qual è il ragionamento dietro Java che ci consente" questo?
Marko Topolnik,

@MarkoTopolnik Perché non ci impedisce: D
Maroun

8
@MarounMaroun Ma qual è il ragionamento alla base che non ci impedisce?
Marko Topolnik,

@Marko Java consente di avere più classi definite nello stesso file (purché solo una di esse sia pubblica). Poiché tutte le classi all'interno dello stesso pacchetto devono avere un nome diverso, non esiste altra opzione che consentire alle classi non pubbliche di avere un nome diverso dal nome del file.
Isnot2bad,

2
I miei 2 centesimi: forse è stato progettato in questo modo per una più rapida localizzazione delle classi all'interno del percorso di classe. Con questa convenzione, l'ispezione dei nomi / percorsi dei file è sufficiente per il rilevamento della classe. Senza questa convenzione, il programma di caricamento classi del percorso di classe potrebbe aver bisogno di aprire e analizzare i file per trovare le classi
Andrei Nicusan,

13

Penso che consentire loro sia un prerequisito per le classi nidificate. Le classi anonime in particolare riducono drasticamente il numero di file .java richiesti. Senza supporto per questo, avresti bisogno di molte implementazioni dell'interfaccia a metodo singolo nei loro file separati dalla classe principale in cui sono usate. (Sto pensando ai listener di azioni in particolare)

C'è una buona spiegazione di tutte le classi nidificate nell'esercitazione Java sulle classi nidificate sul sito Web di Oracle, che contiene esempi di ciascuna. Ha anche una ragione per cui sono utili, che citerò:

Perché usare le classi nidificate?

I motivi convincenti per l'utilizzo delle classi nidificate includono quanto segue:

  • È un modo per raggruppare logicamente le classi che vengono utilizzate solo in una posizione : se una classe è utile solo per un'altra classe, è logico incorporarla in quella classe e tenere insieme le due cose. La nidificazione di tali "classi di supporto" rende il loro pacchetto più snello.

  • Aumenta l'incapsulamento : considera due classi di livello superiore, A e B, dove B ha bisogno di accedere ai membri di A che altrimenti verrebbero dichiarati privati. Nascondendo la classe B all'interno della classe A, i membri di A possono essere dichiarati privati ​​e B può accedervi. Inoltre, B stessa può essere nascosta dal mondo esterno.

  • Può portare a un codice più leggibile e gestibile: l'annidamento di piccole classi all'interno di classi di livello superiore posiziona il codice più vicino a dove viene utilizzato.

(enfatizzare il mio)

All'inizio non ho familiarità con le specifiche Java, ma una rapida ricerca mostra che le classi interne sono state aggiunte in Java 1.1.


Cosa si dovrebbe fare nei casi in cui un tipo è utile solo all'interno di un altro tipo, ma le istanze del primo tipo non sono associate alle istanze di quest'ultimo?
supercat

Le classi nidificate sono il modo Java 1.2 di eseguire lambda o "Funzioni di prima classe quando tutto è un oggetto". Questo sta cambiando in 1.8 Sintassi. Vengono anche utilizzati quando vogliamo modellare i tipi di dati algebrici nel sistema di tipi Java.
falco

12

Lo guardo al contrario. Lo stato naturale delle cose sarebbe per il programmatore di scegliere sia il nome della classe che il nome del file in modo indipendente. Probabilmente per semplificare la ricerca di classi pubbliche al di fuori di un pacchetto durante la compilazione, esiste una speciale restrizione che una classe pubblica si trovi in ​​un file con il nome corrispondente.


4

Nota che Java fa distinzione tra maiuscole e minuscole, ma non è necessario che il filesystem lo sia. Se il nome di base del file è "abcd", ma la classe è "Abcd", sarebbe conforme alla regola su un filesystem senza distinzione tra maiuscole e minuscole? Certamente non se portato su una distinzione tra maiuscole e minuscole.

O supponiamo che ti sia capitato di avere una classe chiamata ABCD e una classe Abcd (non entriamo in quella cattiva idea: potrebbe succedere) e il programma è portato su un filesystem senza distinzione tra maiuscole e minuscole. Ora non devi solo rinominare i file, ma anche classi, oops!

O cosa succede se non ci sono file? Supponiamo di avere un compilatore Java che può accettare input su input standard. Quindi la classe deve essere chiamata "StandardInput"?

Se esplori razionalmente le implicazioni della richiesta di nomi di file per seguire i nomi delle classi, scoprirai che è una cattiva idea in più di un modo.


Sono d'accordo con quello che hai da dire, ma non so che risponda in particolare alla domanda, tranne forse nella misura in cui alcuni dei problemi derivanti dall'architettura dei nomi potrebbero essere risolti consentendo ai nomi di classe non pubblici di essere diversi da nomi dei file. BTW, per quanto riguarda maiuscole e minuscole, se fossi derivare una lingua, in qualsiasi ambito sono stati Fooè stato dichiarato, gli identificatori FOO, foo, fOo, ecc sarebbero tutti "indefinito", anche se esistessero all'interno di ambiti esterni. Un tale progetto eliminerebbe il problema della distinzione tra maiuscole e minuscole per i nomi dei file.
supercat

3

Un altro punto che molte risposte mancano di sottolineare è che senza la publicdichiarazione, la JVM non saprebbe mai quale metodo principale delle classi debba essere invocato. Tutte le classi dichiarate in un file .java possono avere tutti i metodi principali, ma il metodo principale viene eseguito solo sulla classe contrassegnata come pubblica. HTH


0

A causa di un file Java può contenere più di una classe, può avere due classi in un file Java. Ma un file java deve contenere una classe con lo stesso nome del file se contiene una classe pubblica.


No, questa regola è applicabile solo per le classi pubbliche.
deadboy,
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.