JavaClassLoader与Package机制

原创 2007年10月09日 19:07:00

JavaClassLoader与Package机制

[摘要] Java语言规定,在同一个包中的class,如果没有修饰符,默认为Package权限,包内的class都可以访问。但是这还不够准确。确切的说,只有由同一个ClassLoader装载的class才具有以上的Package权限。
[关键字] JavaClassLoader Package
  为了深入了解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权限方法 

Package Manager 的机制与实现

PackageManager的主要功能: 1.权限处理,包括对系统和应用定义的Permission和Permission Group信息的增加、删除、查询和检查 2.包处理,包括扫描并安装和卸载A...
  • u013531215
  • u013531215
  • 2015年05月19日 13:16
  • 183

python的模块和包机制:import和from..import..

写python一段时间了,但是对import和from import却没有深刻的认识。借由官方文档https://docs.python.org/2/tutorial/modules.html,和st...
  • vincent2610
  • vincent2610
  • 2016年12月21日 17:23
  • 2857

java有package和没有package的命令行运行区别

java中不带package的程序和带package的程序编译的方式是不同的。 一、不带package的程序 建立个HelloWorld.java的文件,放入C:,内容如下:public clas...
  • shengzhu1
  • shengzhu1
  • 2017年04月12日 14:23
  • 593

Java中利用package机制实现条件编译

http://www.cnblogs.com/phinecos/archive/2010/03/15/1685965.html
  • wangkaiblog
  • wangkaiblog
  • 2014年09月23日 20:30
  • 432

Java中利用package机制实现条件编译

Java中并没有C语言里的“条件编译”特性。这种特性在C语言里是用来解决代码的跨平台问题的,可以通过让代码的不同部分根据其运行的具体平台进行编译。由于Java本身就设计为一种跨平台的语言,因此这种特性...
  • hjyresdggsd
  • hjyresdggsd
  • 2014年10月12日 13:35
  • 151

struts.xml文件中package元素的各大属性讲解

name: 配置package元素时必须指定name属性,这是引用该包的唯一标识. extends:可选属性,指定该包继承的父包, namespace: abstract:...
  • a_good_programer
  • a_good_programer
  • 2016年11月01日 18:41
  • 2545

从一个简单的例子谈谈package与import机制(下)

提出一个问题:如果把目录\a\b\c全部剪切到其它目录,如D盘根目录下,在\xdj目录如果执行编译和执行命令呢? 很明显,会报以下错误!当然了,前提条件是你没有设置classpath路径...
  • WaitForFree
  • WaitForFree
  • 2014年06月24日 22:51
  • 675

从一个简单的例子谈谈package与import机制(上)

以下内容的测试条件是你的机器上,设置了path命令PATH= D:\JDK1.4\BIN;D:\JDK1.4\LIB;,可以正常执行java和javac命令,不用设置classpath路径的情况下。 ...
  • WaitForFree
  • WaitForFree
  • 2014年06月24日 22:50
  • 553

Python语言(六)import机制

模块化是现代程序语言的一大特点,尤其是随着软件规模yuelaiyuedamodule
  • hjx5200
  • hjx5200
  • 2014年08月22日 10:19
  • 4669

MySQL三种安装方式(rpm、binary package、source)

1、rpm方式 2、二进制方式 3、源码方式 源码安装可能需要的依赖包:ncurses-devel,bison cmake,gcc-c++,make,zlib-devel  使用Oracle官...
  • xiaoyi23000
  • xiaoyi23000
  • 2016年11月17日 15:20
  • 1499
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JavaClassLoader与Package机制
举报原因:
原因补充:

(最多只允许输入30个字)