Differenza tra loadClass (nome stringa) e loadClass (nome stringa, risoluzione booleana)

Qual è la differenza tra loadClass(String name) e loadClass(String name, boolean resolve) ?

L’unica differenza che conosco è loadClass(String name, boolean resolve) chiama findLoadedClass (String) se il parametro di resolve è true?

Quindi quando è vero o falso passato per resolve parametro?
Sono molto confuso tra queste due funzioni.

Grazie.

Il parametro di risoluzione controlla se la class caricata è collegata o meno. Durante il collegamento, le costanti statiche vengono inizializzate e la memoria viene allocata. Inoltre, la class viene verificata per correttezza e verranno eventualmente risolti i collegamenti ad altre classi.

Ciò potrebbe essere utile, ad esempio, se si volesse caricare in una nuova class che potrebbe essere malformata e non si desidera che la JVM lanci errori di verifica nel caso in cui la class sia buggata.

La class è collegata comunque quando viene usata per la prima volta (o almeno le parti usate) – con il flag di resolve è ansible far sì che la VM esegua questo collegamento (e lancia gli errori rilevanti) immediatamente anziché in seguito.

Puoi fare una prova.

 public class Test3 { static{ new Test(); } } 

Dopo la compilazione, modifica la class di test da una class concreta a un’interfaccia.ma rimani il link Test3 a un concreto test di class. Quindi se la risoluzione è falsa, JVM non troverà questo errore. È molto interessante. In realtà, Class someClass1= Class.forName("Test3",false,cls) non risolverà nemmeno Test3. Significa che non verrà generato alcun errore.

Ma se si imposta true in subClass o Class.forName("Test3") , allora JVM nel runtime troverà l’errore di collegamento di class.

 Exception in thread "main" java.lang.InstantiationError: Test at Test3.(Test3.java:6) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:169) 

Per riferimento, le specifiche del linguaggio Java – 12.3 Collegamento di classi e interfacce spiegano cosa risolve resolClass.

12.3 Collegamento di classi e interfacce Il collegamento è il processo di prendere una forma binaria di una class o di un tipo di interfaccia e combinarla nello stato di runtime della macchina virtuale Java, in modo che possa essere eseguita. Un tipo di class o interfaccia viene sempre caricato prima di essere collegato. Tre diverse attività sono coinvolte nel collegamento: verifica, preparazione e risoluzione di riferimenti simbolici . La semantica precisa del collegamento è fornita nel capitolo 5 di Java Virtual Machine Specification, Second Edition. Qui presentiamo una panoramica del processo dal punto di vista del linguaggio di programmazione Java.

12.3.3 Risoluzione di riferimenti simbolici La rappresentazione binaria di una class o di un’interfaccia fa riferimento simbolicamente ad altre classi e interfacce e ai loro campi, metodi e costruttori, utilizzando i nomi binari (§13.1) delle altre classi e interfacce (§13.1). Per i campi e i metodi, questi riferimenti simbolici includono il nome della class o del tipo di interfaccia che dichiara il campo o il metodo, nonché il nome del campo o del metodo stesso, insieme alle informazioni sul tipo appropriate. Prima che un riferimento simbolico possa essere utilizzato deve essere sottoposto a risoluzione, in cui un riferimento simbolico viene verificato per essere corretto e, in genere, sostituito con un riferimento diretto che può essere elaborato in modo più efficiente se il riferimento viene usato ripetutamente.

Se si verifica un errore durante la risoluzione, verrà generato un errore. Più tipicamente, questa sarà un’istanza di una delle seguenti sottoclassi della class IncompatibleClassChangeError , ma potrebbe anche essere un’istanza di qualche altra sottoclass di IncompatibleClassChangeError o anche un’istanza della class IncompatibleClassChangeError stessa. Questo errore può essere lanciato in qualsiasi punto del programma che utilizza un riferimento simbolico al tipo, direttamente o indirettamente:

IllegalAccessError : è stato rilevato un riferimento simbolico che specifica un utilizzo o un’assegnazione di un campo, o l’invocazione di un metodo o la creazione di un’istanza di una class, a cui il codice contenente il riferimento non ha accesso perché il campo o il metodo era dichiarato accesso privato, protetto o predefinito (non pubblico) o perché la class non è stata dichiarata pubblica. Ciò può verificarsi, ad esempio, se un campo che è stato originariamente dichiarato pubblico viene modificato in privato dopo che un’altra class che fa riferimento al campo è stata compilata (§13.4.6).

InstantiationError : è stato rilevato un riferimento simbolico utilizzato in un’espressione di creazione di un’istanza di class, ma non è ansible creare un’istanza perché il riferimento si riferisce a un’interfaccia oa una class astratta. Ciò può accadere, ad esempio, se una class che non è originariamente astratta viene modificata in astratto dopo che un’altra class che fa riferimento alla class in questione è stata compilata (§13.4.1).

NoSuchFieldError : è stato rilevato un riferimento simbolico che fa riferimento a un campo specifico di una specifica class o interfaccia, ma la class o l’interfaccia non contiene un campo con quel nome. Ciò può verificarsi, ad esempio, se una dichiarazione di campo è stata cancellata da una class dopo che un’altra class che fa riferimento al campo è stata compilata (§ 13.4.7).

NoSuchMethodError : è stato rilevato un riferimento simbolico che fa riferimento a un metodo specifico di una class o interfaccia specifica, ma la class o l’interfaccia non contiene un metodo di tale firma. Ciò può verificarsi, ad esempio, se una dichiarazione di metodo è stata cancellata da una class dopo che un’altra class che fa riferimento al metodo è stata compilata (§ 13.4.11). Inoltre, un UnsatisfiedLinkError (una sottoclass di LinkageError ) può essere lanciato se una class dichiara un metodo nativo per il quale non è ansible trovare alcuna implementazione. L’errore si verifica se il metodo viene utilizzato, o prima, a seconda del tipo di strategia di risoluzione utilizzata dalla macchina virtuale (§12.3).