自定义包不能以java开头和为什么不能自定义java.lang.String 类

这里说一下为什么自定义的包不能以 java.xxx.xx 开头,这是一种安全机制,如果以java开头,则直接异常

 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;
    }

如果自己定义了一个 java.lang.String 类,然后执行此类中的方法会出现什么情况 ? 

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

会发出上面的异常,为什么呢?

因为Java的类加载机制造成的,类的加载机制为双亲委派模型,也就是先交给其父亲加载器去加载,如果父亲加载不到,那么再由自己加载

我们自己定义的类一般都由AppClassLoader 进行加载,而它的父亲为ExtclassLoader,而 ExtClassloader的父亲则是 BoostrapClasslader,所以我们自定义的

java.lang.String 最先由 BootStrapClassLoader 加载,而BootStrapLoader 加载器由C++写,它负责加载系统中的类库,而java.lang.string 正是系统中的类,已经被 

BootStrapLoader 加载过了,所以不需要再加载 java.lang.String(虽然我们写的与系统中的不是一个,但名字是一样的),所以这样就会免去了加载而直接执行java.lang.String

中的main方法,而系统中的java.lang.string 中没有main 方法,这也就出现了上面的异常


你可能感兴趣的:(自定义包不能以java开头和为什么不能自定义java.lang.String 类)