为了深入了解Java的ClassLoader机制,我们先来做以下实验:
package java.lang;
public class Test {
public static void main(String[] args) {
char[] c = "1234567890".toCharArray();
String s = new String(0, 10, c);
}
}
String类有一个Package权限的构造函数String(int offset, int length, char[] array),按照默认的访问权限,由于Test属于java.lang包,因此理论上应该可以访问String的这个构造函数。编译通过!执行时结果如下:
Exception in thread "main" java.lang.SecurityException: Prohibited package name:
java.lang
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
奇怪吧?要弄清为什么会有SecurityException,就必须搞清楚ClassLoader的机制。
Java的ClassLoader就是用来动态装载class的,ClassLoader对一个class只会装载一次,JVM使用的ClassLoader一共有4种:
启动类装载器,标准扩展类装载器,类路径装载器和网络类装载器。
这4种ClassLoader的优先级依次从高到低,使用所谓的“双亲委派模型”。确切地说,如果一个网络类装载器被请求装载一个java.lang.Integer,它会首先把请求发送给上一级的类路径装载器,如果返回已装载,则网络类装载器将不会装载这个java.lang.Integer,如果上一级的类路径装载器返回未装载,它才会装载java.lang.Integer。
类似的,类路径装载器收到请求后(无论是直接请求装载还是下一级的ClassLoader上传的请求),它也会先把请求发送到上一级的标准扩展类装载器,这样一层一层上传,于是启动类装载器优先级最高,如果它按照自己的方式找到了java.lang.Integer,则下面的ClassLoader都不能再装载java.lang.Integer,尽管你自己写了一个java.lang.Integer,试图取代核心库的java.lang.Integer是不可能的,因为自己写的这个类根本无法被下层的ClassLoader装载。
再说说Package权限。Java语言规定,在同一个包中的class,如果没有修饰符,默认为Package权限,包内的class都可以访问。但是这还不够准确。确切的说,只有由同一个ClassLoader装载的class才具有以上的Package权限。比如启动类装载器装载了java.lang.String,类路径装载器装载了我们自己写的java.lang.Test,它们不能互相访问对方具有Package权限的方法。这样就阻止了恶意代码访问核心类的Package权限方法。
分享到:
相关推荐
`CH_05.package与import机制.pdf`可能讲解了与ClassLoader相关的包和导入机制,因为它们与类的组织和加载密切相关。 `CH_03.Java与MS Office.pdf`、`CH_04.用Visual Studio.net来操控Java虚拟机.pdf`、`CH_06.Ant....
总之,`package`和`import`机制为Java程序提供了良好的结构和可维护性,Visual Studio .NET提供了与JVM交互的便捷方式,而Java 2 SDK则为开发者提供了丰富的工具和资源。深入理解这些概念和工具,对于任何Java开发者...
通过类加载器(Class Loader),Java程序能够在运行时根据需要加载所需的类,从而实现高度的灵活性与可扩展性。本文将深入探讨Java中的类加载机制,并通过一个具体的自定义类加载器的例子来帮助理解其工作原理。 ##...
总之,Java反射机制与动态代理为开发者提供了强大的灵活性,可以在运行时探索和修改程序行为,实现更复杂的设计模式和编程策略。然而,由于它们涉及底层操作,过度使用可能会影响程序性能和安全性,因此在实际应用中...
当Java运行时环境(JRE)需要使用某个类时,它会通过类加载器(ClassLoader)来查找并加载。默认情况下,类加载器会遍历ClassPath中的所有位置,包括JAR文件,寻找指定包下的类。如果同一个包中的类分散在多个JAR中...
- **Package与Import**:Java中的`package`用于组织类文件,`import`则用来引入其他包中的类。理解这两个机制对于管理类文件路径非常重要。 #### 二、掌握Java基本语法 接下来,需要快速掌握Java的基本语法。由于...
Java 类加载机制是Java虚拟机(JVM)的关键特性之一,它负责将类的字节码文件加载到内存中,并转换为对应的类对象。在Java中,类加载器(ClassLoader)扮演着至关重要的角色,它们负责查找和加载类。本文将深入探讨...
### JAVA手机程序入门2:深入理解Java包机制与动态链接本质 #### Java包机制:构建模块化编程的基础 Java的包机制(Package Mechanism)是Java语言为了支持大型项目管理和组织代码而设计的一个重要特性。它允许...
7. Java的包和访问控制:Java的包(package)机制可以帮助组织类和接口,同时Java提供了四种访问控制修饰符:public、protected、默认(无修饰符)、private。 8. Java与C/C++的比较:尽管Java与C和C++都继承了...
Java RT包,全称为Runtime Library Package,是Java标准版(Java SE)的核心库,包含了运行Java应用程序所必需的基础类库。这些类库构成了Java平台的基础,提供了系统操作、内存管理、网络通信、I/O流、多线程、集合...
`ClassLoader`是Java和安卓系统中的一个重要组件,它的主要职责是加载类到Java虚拟机(JVM)或者 Dalvik 虚拟机(DVM)中。在安卓环境下,`ClassLoader`负责解析应用的`.apk`文件,提取`.dex`文件,并将其转换为可...
在Java编程语言的世界里,深入了解其底层机制是提升开发能力和优化代码的关键。本文将带你深入探索Java的包管理、类加载器以及import等核心概念,帮助你更好地理解Java运行时环境的工作原理。 1. **包管理**: ...
3. **包和导入**:Java使用包(package)进行模块化管理,例如`java.util`包包含许多实用工具类。`import`语句用于引入特定包中的类,如`import java.util.*`导入整个`java.util`包。 4. **类和对象**:Java是一种...
2. **Package与Import机制**:Java中的package用于组织类,import则用于引入特定包中的类。掌握这两者的工作原理,能够帮助开发者在大型项目中有效地管理类文件,避免命名冲突。 #### 二、语法入门:从C到Java的...
2. 将源代码文件保存在与包名对应的目录结构中:`src/com/example/animals/Dog.java` **访问控制修饰符**: - `public`:允许从任何地方访问。 - `protected`:允许在同一包内以及子类中访问。 - `default`(无...
Java反射机制是Java语言提供的一种强大的工具,它允许程序在运行时动态地获取类的信息以及对类的对象进行操作。在Java中,一切皆为对象,类也不例外。`java.lang.Class`类是反射的起点,它代表了Java运行时的类信息...
Java的标准库中包含了诸多的包(package),比如java.lang.*、java.io.*、java.util.* 和 java.sql.*,这些包提供了丰富的类和接口,是开发Java程序的基础。此外,JDK的文档(Documentation)是学习Java API和理解...