Original: http://www.wfuyu.com/php/22254.html
Test not done!
Recently learned the next Java class loading coherence knowledge. And then see that there are 1 interview questions online
Can you write a class called Java.lang.System?
Answers available online: usually not, but alternative approaches can be taken to reach this requirement. The so-called alternative method refers to writing a class loader to load the Java.lang.System.
First of all, to show my point. The above answer is completely misleading and is an incorrect answer. I wondered how this sort of completely incorrect search results would be put in front of the web, and almost all of this was an incorrect answer. Perhaps a lot of unknown truth friends are so misled, so I still hope that the content of the online first to be skeptical as well. The following details explain why.
First, a detailed explanation of the answer to the online problem
"In order not to let us write the system class, class loading takes the mechanism of asking, so that dads will be given priority, and dads can find classes that the son has no chance to load." The system class is loaded by the bootstrap loader, and even if you rewrite it, you always use the system provided by the Java systems, and the system class you write does not have a chance to get loaded at all.
However, we can define 1 class loaders ourselves to achieve this, and the ClassLoader must be special for the sake of the parent-to-person mechanism. Because the system comes with 3 class loaders loaded in a specific directory of the class, if our own ClassLoader placed in 1 special directories, then the system loader will not be able to load, that is, after all, it is still loaded by our own loader. ”
Then, explain the 1 concepts mentioned in the explanation above
Class loaders can be divided into two categories: 1 is the startup class loader (Bootstrap ClassLoader), is implemented by C + +, is 1 parts of the JVM, and the other class loader, which is implemented in Java, is independent of the JVM, All inherit from the abstract class Java.lang.ClassLoader. The JDK comes with 3 kinds of loaders, which are the Boot class loader (Bootstrap ClassLoader), which expands the ClassLoader (Extension ClassLoader) with the Program class loader (application ClassLoader). The latter two types of loaders are inherited from the abstract class Java.lang.ClassLoader. about the respective functions of these 3 loaders do not elaborate here, interested can be understood under their own.
The class loader is hierarchical
1 like: Custom ClassLoader >> Use program ClassLoader >> enlarge class loader >> start class loader
The above hierarchy is called the parental delegation model (parents delegation models). In addition to the topmost startup class loader, the rest of the ClassLoader has a corresponding parent classloader.
Let's just say, parents, please. Mechanism: if the 1 class loader receives the class loading requirements, it first does not try to load the class itself, but to delegate this request to the parent class loader, each level of the ClassLoader is added, so all the loading requirements eventually reach the top level of the Startup class loader, The subclass loader will attempt to load itself only if the parent loader feedback that it is unable to complete the load requirement (meaning that its search scope does not find the desired class).
If we go back and look at the explanations, I believe that we should understand them very well and have no major problems. The final if part "if our own ClassLoader is placed in 1 special directories, then the system loader will not be able to load, that is, after all, it is loaded by our own loader." "I don't understand so, the logic is completely out of the way. I think it's meant to be, to put their own Java.lang.System class in a special directory, and then the system comes with the loader can not load, so it is still loaded by our own loader (because our own loader know its special directory). There seems to be no logical problem with this kind of argument, so let's experiment with it.
Code Validation
Test class structure and content below:
public class Myclassloader extends classloader{public Myclassloader () {super (null);} @Override public class<?> lo Adclass (string name) throws ClassNotFoundException {try{string className = null, if (Name.startswith ("Java.lang")) {Clas SName = "/" + name.replace ('. ', '/') + ". Class"; }else{className = name.substring (Name.lastindexof ('. ') + 1) + ". Class";} System.out.println (ClassName); InputStream is = GetClass (). getResourceAsStream (ClassName); System.out.println (IS); if (is = = null) return Super.loadclass (name); Byte[] B = new byte[is.available ()]; Is.read (b); Return DefineClass (name, b, 0, b.length); }catch (Exception e) {e.printstacktrace (); throw new ClassNotFoundException ();}} }public class Classloadertest {public static void main (string[] args) throws ClassNotFoundException, instantiationexcept Ion, illegalaccessexception {ClassLoader myloader = new Myclassloader (); Object obj = Myloader.loadclass ("Java.lang.Math"). newinstance (); System.out.println (obj); }}public FinAl class Math {public static void main (string[] args) {System.out.println ("Hello World");}} public class MyMath {public static void main (string[] args) {System.out.println ("Hello World");}}
The above test code does not use the custom Java.lang.System class, because the test code uses the JDK's own system class for output printing, conflicts, so instead of the custom Java.lang.Math class. If the custom math class can load, then the custom system class can be loaded as well.
Let's run the math class directly and output the following:
Java.lang.NoSuchMethodError:main
Exception in thread "main"
Tip The Math class has no Main method. First of all to understand the 1 concepts, when the first active use of the class, the class must be loaded, this part of the work is done by the ClassLoader. According to the parents ' principle, the math class was first tried to load by the boot loader, and it was clear that It finds the Java.lang.Math class in Rt.jar and loads it into memory (in fact it does not load our custom math Class) and then fulfills the main method and finds that there is no such method, so there is no problem with the report method. In other words, the JVM does not load our custom math class in the case of acquiescence.
Then run the MyMath class directly and output the following:
Java.lang.SecurityException:Prohibited Package Name:java.lang
at Java.lang.ClassLoader.preDefineClass ( classloader.java:479)
at Java.lang.ClassLoader.defineClassCond (classloader.java:625)
at Java.lang.ClassLoader.defineClass (classloader.java:615)
at Java.security.SecureClassLoader.defineClass ( secureclassloader.java:141)
at Java.net.URLClassLoader.defineClass (urlclassloader.java:283)
at java.net.urlclassloader.access$000 (urlclassloader.java:58)
at Java.net.urlclassloader$1.run ( urlclassloader.java:197)
at java.security.AccessController.doPrivileged (Native Method)
at Java.net.URLClassLoader.findClass (urlclassloader.java:190)
at Java.lang.ClassLoader.loadClass ( classloader.java:306)
at Sun.misc.launcher$appclassloader.loadclass (launcher.java:301)
at Java.lang.ClassLoader.loadClass (classloader.java:247)
Exception in thread "main" &NBSP;
Note the contents of the Red section. By the stack exception information, when you try to load the MyMath class with the Program class loader class (Appclassloader), the 479 rows of Classloader.java throw out the SecurityException
Stop using Package name: Java.lang.
Look directly at the Predefineclass method code of the abstract class Java.lang.ClassLoader, excerpt from the following:
Private Protectiondomain Predefineclass (String name, Protectiondomain protectiondomain) {if (!checkname (name)) throw New Noclassdeffounderror ("Illegalname:" + name); if ((name! = null) && name.startswith ("java.")) {throw new SecurityException ("Prohibited Package Name:" + name.substring (0, Name.lastindexof ('. ')));} if (Protectiondomain = = null) {Protectiondomain = GetDefaultDomain ();} if (name! = null) checkcerts (name, Protectiondoma In.getcodesource ()); return protectiondomain; }
You can see if the class full name is loaded with "java." At the beginning, SecurityException will be thrown, which is why the direct fulfillment MyMath class will appear SecurityException.
In this way, our custom ClassLoader must inherit from ClassLoader, whose loadclass () method calls the DefineClass () method of the parent class, and eventually it is transferred to the Predefineclass () method, So our custom class loader is also not loaded with "java." The beginning of the Java class. We continue to run the next Classloadertest class, outputting the following:
/java/lang/math.class
[Email Protected]ca
java.lang.SecurityException:Prohibited Package Name:java.lang
At Java.lang.ClassLoader.preDefineClass (classloader.java:479)
At Java.lang.ClassLoader.defineClassCond (classloader.java:625)
At Java.lang.ClassLoader.defineClass (classloader.java:615)
At Java.lang.ClassLoader.defineClass (classloader.java:465)
At Com.tq.MyClassLoader.loadClass (myclassloader.java:28)
At Com.tq.ClassLoaderTest.main (Classloadertest.java:8)
Exception in thread "main" java.lang.ClassNotFoundException
At Com.tq.MyClassLoader.loadClass (myclassloader.java:31)
At Com.tq.ClassLoaderTest.main (Classloadertest.java:8)
The Red section clearly indicates that the SecurityException is also thrown in the Predefineclass method.
Through code examples and source analysis can be seen, to the custom class loader, forced to use the DefineClass () method to load 1 "java." The class at the beginning will also throw an exception.
Summarize
Cannot write by itself "java." At the beginning of the class, it should not be loaded into memory at the end, even if you use a custom class loader to forcibly load, you will receive 1 SecurityException.
Code word is not easy, source from http://blog.csdn.net/tang9140.
Those who crawl online content, on their own website, please consciously. Baidu Search Why do you keep the original page row behind it, please reflect, do not just want to make money.
Java can write itself a class called java.lang.system/string correct answer