2011-07-10 3 views
11

Sto sviluppando un'applicazione in Java ME che desidero fornire come libreria. Non c'è modo di nascondere classi che non voglio vengano utilizzate da tutti, ma è essenziale che la libreria funzioni ancora?Fornire libreria Java, ma nascondere alcune classi

AGGIORNAMENTO: Ottengo che posso omettere lo specificatore pubblico, ma come posso strutturare la libreria stessa durante lo sviluppo senza creare pacchetti diversi? Mi piace visualizzare diversi pacchetti semplicemente come cartelle diverse, il che mi consente di strutturare il codice in modo corretto. Tuttavia, in alcuni casi potrei aver bisogno di accedere alle classi in altri pacchetti, quindi è piuttosto complicato. Cosa rappresentano veramente i pacchetti? Un'idea potrebbe essere quella di creare "interfacce", ma queste devono essere dichiarate pubbliche in modo che gli stranieri possano anche implementare le interfacce destinate solo ad alcuni processi all'interno della libreria, corretto?

+0

renderli "finale". – daGrevis

+2

Rendere la classe finale proibirà solo la sua sottoclasse. Sarà ancora esposto. – thunderflower

+0

Dipende da cosa intendi per "vuoi" e quanti problemi vuoi andare. Ad esempio, i modificatori di accesso sono facili da aggirare con la riflessione. – CurtainDog

risposta

-3

È necessario rendere le classi che non si desidera proteggere esposte. Ciò li renderà non utilizzabili dal codice cliente. Altre informazioni in the official docs

+0

La parte che ti serve: lascia la parola chiave 'public' nella dichiarazione della classe, quindi la classe è accessibile solo ad altre classi nello stesso pacchetto. – Brabster

+1

Non è possibile utilizzare il modificatore 'protected' per le classi, solo per i membri. L'unico modo per limitare l'accesso alla tua classe è omettere il modificatore 'public' rendendolo visibile solo all'interno del suo pacchetto. – Muzikant

1

È possibile creare le classi package protected che solo le altre classi nello stesso pacchetto possono vedere. Se ciò non è possibile, è possibile utilizzare ProGuard per manipolare le classi e nascondere le loro implementazioni.

+0

Grazie, sì guarderò ProGuard –

+0

Non è possibile utilizzare il modificatore 'protected' per le classi, solo per i membri. L'unico modo per limitare l'accesso alla tua classe è omettere il modificatore 'public' rendendolo visibile solo all'interno del suo pacchetto. – Muzikant

0

Sì, c'è.

Semplicemente non dichiarare tali classi public. In altre parole, omettere la parola public modo:

class Internal { // rather than "public class Internal" 
    ... 
} 

Per default, le classi sono accessibili solo all'interno del pacchetto in cui sono definite.

0

Consente di considerare un esempio:

Se si dispone di una classe A, che si desidera nascondere, e una classe B, che utilizza la funzionalità di classe A, allora si può fare questo:

class B{ 
//Attribute and Methods 

    //Inner class A 
    class A{ 
     //Methods and Attributes. 
    } 

} 

Dopo aver fatto ciò, è possibile creare un oggetto di classe A all'interno di un metodo di classe B e quindi usarlo. Anche se la classe sarà nascosta da altre classi, potrebbe comunque essere utilizzata.

+0

Rendere una classe interna non la nasconde al mondo esterno. Puoi ancora importarlo e usarlo. L'accesso a livello di pacchetto che hai usato, tuttavia, nasconderà le classi da altri pacchetti. –

4

Per impostare l'API della libreria, è necessario proteggere tutto ciò che si desidera non esposto a . Non fare questo basta omettere il modificatore di accesso:

class fooBar { 
    // do stuff here  
} 

Questo imposterà l'accesso classe come 'default', che consente l'accesso da all'interno dello stesso pacchetto così come da tutte le classi che sottoclasse fooBar.

All'interno delle classi si desidera anche bloccare qualsiasi accesso ai propri metodi e membri contrassegnandoli o private, protected o omettendo il modificatore in modo che siano 'predefiniti' come richiesto.

  • private consentirà l'accesso solo dalla classe contenente;
  • 'default' (nessun modificatore) consente dall'interno della classe contenente e del pacchetto contenente; e
  • protected consentirà l'accesso dalla stessa classe, pacchetto e qualsiasi sottoclasse.

per tutto ciò che si è esposto (public) è anche buona pratica per contrassegnare come final se non è stato progettato per essere sovrascritto.

Fondamentalmente, bloccare tutto il più possibile. Le API più piccole sono più facili da usare e più difficili da rompere. Se trovi qualcosa che deve essere esposto in futuro, fallo in futuro. È molto più semplice espandere un'API piuttosto che deprecarne parti.

+2

Grazie! Ma come dici tu, posso usare solo la classe fooBar all'interno dello stesso pacchetto. Qual è il solito modo di strutturare un progetto Java? Ho creato pacchetti basati su cose diverse che fanno le classi. Ad esempio, ho un pacchetto che chiamo com.comms dove memorizzo le routine e le classi per la trasmissione tramite socket. Poi ho un altro pacchetto (come il livello dell'applicazione) che usa il pacchetto delle comunicazioni. Ma immagino che, per creare un'API come questa, dovrei avere tutte le classi nello stesso pacchetto? –

+3

Sì, come si può fare quando si ha una libreria con più pacchetti? –

+0

Per impostazione predefinita le classi hanno visibilità predefinita e quindi la visibilità è solo all'interno del pacchetto. Puoi anche impostarlo per essere protetto in modo esplicito e avrà anche lo stesso scopo, – Tarun

0

Se Java 9 è possibile, utilizzare Jigsaw modules. In caso contrario, inserire tutte le classi nello stesso pacchetto, con accesso a livello di pacchetto per le classi nascoste e utilizzare Maven modules per organizzarle.

Ho fatto esattamente questo nel mio progetto chiamato coronata, una libreria java Wii Remote. Quasi tutte le classi sono nel pacchetto com.github.awvalenti.bauhinia.coronata, ma su diversi moduli (che appaiono come progetti sull'IDE).

Le classi visibili sono pubbliche. Essi sono in moduli:

  • coronata-api
  • coronata-builder
  • coronata-demos
  • coronata-lib

classi nascosti sono a livello di pacchetto acesss. Sono in moduli:

  • coronata-common
  • coronata-implementation-bluecove
  • coronata-implementation-wiiusej