关于java的几个困惑问题

关于java的几个困惑问题
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同时安装呢?
于是到网上查查,发现王森写得《java深度历险》里有我要得答案:因为jdk里的很多工具本身就是用java写的,所以它们也需要jre来运行,因此jdk底下要有一套jre。
而另外一个jre是用来运行我们自己编写的java程序的。当然我们完全可以只用一个jre就可以。不搞开发的,只用下载独立的jre来安装就可以。搞开发的完全可以只下载jdk下来安装就可以。
2.path和classpath。
 这个问题困扰了我很久了,以前一直都是按着网络上的设置照搬了事,但是一直不明白为什么要这么设置。这其中其实涉及到比较多的问题:比如操作系统的环境变量的作用,path和classpath的作用,以及java加载类的路径(即它如何找到所需要的类)。
http://mindprod.com/jgloss/environment.html。这篇文章里说到Different operating systems use different methods of storing parameter and configuring data for programs. This list of parameters, usually including PATH and CLASSPATH, is called the set environment.
简单地说,环境变量就是用来保存运行程序要用到的一些参数:比如path和classpath等。(环境变量是大小写不分的).那么path和classpath的作用又是什么?In contrast, the PATH is an environment variable that tells the command processor the where to look for executable files, e.g. *.exe, *.com and *.bat files.
The CLASSPATH is an environment variable that tells the Java compiler javac.exe where to look for class files to import or java.exe where to find class files to interpret. 那么classpath是不是只有java程序才用到?这个变量是不是sun公司的专用?没有别的公司的程序也用这个变量,或者也是自己的专用变量?比如c#的又是这么样?这个还不得而知。
要注意的问题,当你改变环境变量后,要先关闭先前那个dos窗口。改后的环境变量只有对接下来打开的dos窗口有用!其次要注意如果你同时在用户变量和系统变量同时设置了path,则最终的path是二者的累加;但是如果同时设置了classpath那么以用户变量的为准.
3.如何查找jre.
 当在控制台执行java.exe,操作系统寻找JRE的方式如下:先找当前目录下有没有JRE,再找父目录下有没有JRE,接着在PATH路径中找JRE,最后再注册表HKEY_LOCAL_MACHINESOFTWAREJavaSoftJava Runtime Environment 查看CurrentVersion的键值指向哪个JRE.
最常用的是在PATH路径中找JRE,一般情况下,自己的程序运行之前都会先在批处理文件里面临时设置PATH,把自己用的JRE放到PATH路径最前面,所以肯定会运行自己带的JRE,不会造成版本混乱。
4.虚拟机如何启动和加载类库
 在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在JREin目录下寻找某某DLL文件,调入内存,于是实现了JNI调用。
5.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参数指定路径的类库。
6.加载类库的顺序.
 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权限方法。
7.Eclipse如何查找jre
 Eclipse查找JRE的三个地方:首先去启动参数-vm设定的路径查找,如果没有设定该参数,则查找安装目录下的jre子目录,如果还没有,Eclipse将查找当前Windows系统默认的JRE。
8.java.exe与javaw.exe的区别
 用java命令运行Java程序会出现DOS界面的,GUI界面在前面,DOS界面出现在后面.javaw运行时候没有DOS界面.其他没有区别了.那么如果只有这么点区别,那为什么要两个命令呢?还不得而知,期待深入了解!
(涉及本次思考的好文章"关于 java.exe 是如何载入 JVM
" http://java.chinaitlab.com/Jvm/21229.html)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值