您的位置:首页 > 编程语言 > Java开发

关于java的几个困惑问题

2007-03-25 00:50 375 查看
1.两个jre的作用。
一般sun公司会在网上提供jdk和jre两种下载。以前我知道jdk中已经包含了jre,因此安装了jdk,就不用再单独安装jre。但是我们在安装jdk时却出现让你再次安装jre的选现。当然你可以不用选择,但是当你选择了安装。那么安装完我们就会发现,在C:/Program Files/Java /jdkxxx(版本号)下有个jre,而在C:/Program Files/Java(跟jdk同目录)也有一个jre(可能多了版本号)。点进去一看目录结构基本一样。这就奇怪了,为什么sun公司要把两个基本一样的jre同时安装呢?
因为jdk里的很多工具本身就是用java写的,所以它们也需要jre来运行,因此jdk底下要有一套jre。
而另外一个jre是用来运行我们自己编写的java程序的。当然我们完全可以只用一个jre就可以。不搞开发的,只用下载独立的jre来安装就可以。搞开发的完全可以只下载jdk下来安装就可以。

2.如何查找jre.
当在控制台执行java.exe,操作系统寻找JRE的方式如下:先找当前目录下有没有JRE,再找父目录下有没有JRE,接着在PATH路径中找JRE,最后再注册表HKEY_LOCAL_MACHINESOFTWAREJavaSoftJava Runtime Environment 查看CurrentVersion的键值指向哪个JRE.
最常用的是在PATH路径中找JRE,一般情况下,自己的程序运行之前都会先在批处理文件里面临时设置PATH,把自己用的JRE放到PATH路径最前面,所以肯定会运行自己带的JRE,不会造成版本混乱。


3.虚拟机如何启动和加载类库
在Console执行java.exe xxx命令以后,如前所述的寻找JRE,OS找到JRE目录,根据java.exe的传递参数,选择加载Server版的jvm.dll还是Client版的jvm.dll,然后加载jvm.dll,把控制权交给jvm.dll。
接下来,jvm.dll进行初始化,分配内存等等动作,然后在CLASSPATH路径中寻找class,找到class以后,寻找class中的程序入口点Main函数,然后从Main函数执行程序,在执行过程中,使用ClassLoader动态加载一系列引用到的类。当调用到native方法时,jvm.dll告诉OS在JRE.in目录下寻找某某DLL文件,调入内存,于是实现了JNI调用。

4.JRE类库的查找方法和版本管理.
JRE中由ClassLoader负责查找和加载程序引用到的类库,基础类库ClassLoader会到rt.jar中自动加载,其它的类库,ClassLoader在环境变量CLASSPATH指定的路径中搜索,按照先来先到的原则,放在CLASSPATH前面的类库先被搜到,Java程序启动之前建议先把PATH和CLASSPATH环境变量设好,OS通过PATH来找JRE,确定基础类库rt.jar的位置,JRE的ClassLoader通过CLASSPATH找其它类库。但有时候会出现这样的情况,希望替换基础类库中的类库,那么也可以简单的通过-Djava.endrosed.path=...参数传递给java.exe,于是ClassLoader会先于基础类库使用java.endrosed.path参数指定路径的类库。

5.加载类库的顺序.
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权限方法。

6.Eclipse如何查找jre

Eclipse查找JRE的三个地方:首先去启动参数-vm设定的路径查找,如果没有设定该参数,则查找安装目录下的jre子目录,如果还没有,Eclipse将查找当前Windows系统默认的JRE。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: