Can java write a correct answer to a class called java. lang. System/String? java. lang. string

Source: Internet
Author: User
Tags java throws

Can java write a correct answer to a class called java. lang. System/String? java. lang. string

I recently learned about java class loading. Then we can see that there is an interview question on the Internet:

Can I write a class called java. lang. System?

Answer provided on the Internet: it is usually not acceptable, but an alternative method can be used to meet this requirement. The so-called alternative method means writing a class loader to load java. lang. System.

First, let me express my point of view. The answer above is totally misleading and incorrect. I wondered how to rank this completely incorrect search result on the Internet, and almost all I found was this incorrect answer. Many friends who do not know the truth may be misled, so it is better to be skeptical about the content on the Internet. The following describes in detail why.

First, extract a detailed explanation of the online incorrect answer

"In order to prevent us from writing System classes, class loading adopts a delegation mechanism, which ensures that the class members are given priority and the class they can find will not be loaded by their son. The System class is loaded by the Bootstrap loader. Even if you rewrite it yourself, you always use the System provided by the Java System. The System class you write has no chance to load it.
However, we can define a class loader to achieve this goal. To avoid parent-parent delegation, this class loader must also be special. Because all the three class loaders in the system load classes under a specific directory, if our own class loaders are placed in a special directory, the system's loaders cannot be loaded, that is to say, it is still loaded by our own loader."

Then, explain the concepts mentioned above

The class loader can be divided into two types: one is the Bootstrap ClassLoader, which is implemented by C ++ and part of JVM; the other is other class loaders implemented in Java, independent from JVM, all inherited from the abstract class java. lang. classLoader. Jdk comes with three types of loaders: Bootstrap ClassLoader, Extension ClassLoader, and Application ClassLoader ). The last two loaders inherit from the abstract class java. lang. ClassLoader. The roles of these three loaders are not described in detail here. If you are interested, you can understand them.

The class loader is hierarchical.

Generally: Custom class loaders> application class loaders> extended class loaders> started class loaders

The preceding hierarchy is called the Parents Delegation Model ). In addition to the top-level start class loaders, all other class loaders have corresponding parent class loaders.

Simply put, the parent-parent delegation mechanism: If a Class Loader receives a class loading request, it will not first attempt to load the class, But delegate the request to the parent class loader, this is added to the class loaders at each layer. Therefore, all loading requests will eventually reach the top-level start class loaders, only when the parent class loader reports that it cannot complete the loading request (that its search range does not find the desired class) Will the subclass loader attempt to load it by itself.

Let's go back and look at the explanation. I believe that the previous sections are very understandable and there is no major problem. The final part of "if our own class loader is placed in a special directory, the system loader will not be able to load, that is, it will eventually be loaded by our own loader ." I don't understand, so the logic is completely different. I think its intention may be to put its own java. lang. the System class is placed in a special directory, and the System's built-in loader cannot be loaded, in this way, it is still loaded by our own loader (because our own loader knows its special directory ). This statement seems to have no logic problems, so let's experiment.

Code Verification

The structure and content of the test class are as follows:


public class MyClassLoader extends ClassLoader{        public MyClassLoader() {        super(null);    }        @Override    public Class<?> loadClass(String name) throws ClassNotFoundException {        try{            String className = null;            if(name.startsWith("java.lang")){                className = "/" + 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, InstantiationException, 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 custom java. lang. system class, because the test code uses the JDK built-in System class for output printing, it will conflict, so use the custom java. lang. math class. If the custom Math class can be loaded, the custom System class can also be loaded.

Run the Math class directly. The output is as follows:

Java. lang. NoSuchMethodError: main
Exception in thread "main"

The system prompts that the Math class does not have the main method. First, you need to understand the concept that when a class is actively used for the first time, class loading is required. This part of work is done by the class loader. According to the parent-child delegation principle, the Math class is first loaded by the start class loader. Obviously, it finds rt. java. lang. the Math class is loaded into the memory (the custom Math class is not loaded). When the main method is executed, the method does not exist. Therefore, an error indicating that the method does not exist is reported. That is to say, by default, the JVM will not load our custom Math class.

Run the MyMath class directly, and the output is as follows:

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"

Pay attention to the content in red. The stack exception information shows that when the application Class Loader class (AppClassLoader) tries to load the MyMath class, row 479 of ClassLoader. java throws a SecurityException

Disable package name: java. lang.

View the preDefineClass method code of the abstract class java. lang. ClassLoader. The excerpt is as follows:

    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, protectionDomain.getCodeSource());return protectionDomain;    }

It can be seen that if the full name of the loaded class starts with "java.", SecurityException will be thrown, Which is why SecurityException occurs when you directly execute the MyMath class.

In this way, the custom Class Loader must inherit from the ClassLoader. Its loadClass () method calls the defineClass () method of the parent class, and finally transfers it to the preDefineClass () method, therefore, the custom Class Loader cannot load.. Continue to run the ClassLoaderTest class. The output is as follows:

/Java/lang/Math. class
Sun.net. www. protocol. jar. JarURLConnection $ JarURLInputStream @ a981ca
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 part clearly indicates that SecurityException is also thrown in the preDefineClass method.

Through code examples and source code analysis, we can see that for a custom class loader, forcing the defineClass () method to load a class starting with "java." also throws an exception.

Summary

You cannot write a class that starts with "java." by yourself. It cannot either be loaded into the memory or receive a SecurityException even if you use a custom class loader to forcibly load the class.

The code word is not easy. The source is http://blog.csdn.net/tang9140.

Those who crawl online content and put it on their own websites should be conscious. Baidu search: Why are you always following the original webpage? Please reflect on it and don't just think about making money.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.