Java基础——path, classpath, JAVA_HOME, JRE, JDK等基本原理

时间:2021-10-22 19:44:07

 

什么是环境变量

环境变量其实就是一组变量,就如你在java编程的时候需要定义的变量一样,它的作用是给系统和应用程序提供参数。具体到细节,例如path,它是系统中的一个重要变量,它告诉系统和应用程序一些系统必备的程序的存储位置,例如你想在命令行窗口中使用ipconfig命令查看自己的ip地址,可是系统怎么知道ipconfig这个程序在什么位置呢?答案是通过path,从头到尾挨个的取出每个参数来试,例如path中有个C:/WINDOWS/system32的话,那么它就加上ipconfig,看能不能找到程序,现在也就是说变成了C:/WINDOWS/system32/ipconfig如果能找到它的话就运行,不能的话就返回“‘ipconfig’不是内部或外部命令,也不是可运行的程序或批处理文件。

Path

而对于java来说,你在命令行里面输入java xxx的话系统同样不知道java这个exe文件的位置,同样需要你显式的指出,java这个程序在哪呢?在你的jdk安装路径/bin文件夹里面,也就是说要想运行javapath必须指向bin文件夹。

还有一个classpath,现在系统能找到java这个程序了,但是仅仅这样的话,你在命令行中输入javac的话,又出现错误了,也许有人会说你不是说系统通过path找到了,应该能找到我设置的bin文件下的javac程序呀?这里要说的是,虽然你已经设置好了path但是系统还是有些东西找不到,什么东西呢?Java的类库文件,大家知道java的源程序上面总是有很多的形如import java.xx.xx;的语句,这就是引用的java的类库,也许有人会问,我的程序中没有这一句话呀,对,很多简单的程序都没有,例如经典的“Helloworld”里面就没有,对它是没有显式的引用,但是在每个java文件中都隐藏了这么一句“import java.lang.*”;现在问题就出来了,程序怎么才能找到这个lang这个包并且把里面的类导进去呢?显然只通过path是不行的,那么就只能另外的定义一个变量来指向类库文件。它就是classpath,为什么叫这个名字呢?不为什么,就规定了必须用这个名字,它必须叫这个名字,可以理解为它是在javajdk中定义的一个static的变量,既然已经定义好了,你只用给它赋值就得了,然过jdk调用的时候它没有值,就是说你没有新建一个classpath并且给它赋值,那么没办法,就给你脸色看。

 

另外还有一点就是可能有人会问JAVA_HOME变量是一个什么变量呀,这个变量在目前的阶段来说就是一个我们自己定义的变量,它作用就是让你省劲,例如你的jdk安装的路径很深,譬如安装到了“C:/ProgramFiles/Sun/Java/jdk1.6.0_02/”下边然后你在设置path的时候必须输入“C:/Program Files/Sun/Java/jdk1.6.0_02/bin”,设置classpath的候再来一次“C:/ProgramFiles/Sun/Java//jdk1.6.0_02/lib/tools.jar”,你不累系统都烦了,而且pathclasspath也变得很长了,下一次设置的时候就变得很麻烦了,要找半天才能找到自己要改的地方,现在JAVA_HOME就出现了,你可以在系统中定义一个名为JAVA_HOME的环境变量,它的值是:“C:/ProgramFiles/Sun/Java/jdk1.6.0_02”,那么在设置path的时候就可以直接写了,在path的值里面添加:“%JAVA_HOME%/bin”,就是这么简单,相应的classpath为:“,;%JAVA_HOME%/tools.jar”是不是简洁多了呢?而且你的安装路径变了或者写错的时候要改也只用改这一处,不用把pathclasspath同时修改。到了这里我继续叨叨几句,JAVA_HOME可以不大写,甚至名字都可以变成“sxy”“a”,或者你能想到的其他,反正只要在引用它(就是系统在看到有%%围绕的变量时就把它替换成变量的值,例如上面的“%JAVA_HOME%/bin”系统看到这个的时候就把%JAVA_HOME%变成了C:/ProgramFiles/Sun/Java/jdk1.6.0_02)保证名称一样(大小写不敏感),但是如果以后你要是使用tomcat等软件的时候,它会检查你的JAVA_HOME变量,所以最好保持这个名字不变,但是你如果现阶段不用,就随便了。现在明白了,也许有人会说我啰嗦,没办法放出一个环境变量的例子来:

 

JAVA_HOME=C:/ProgramFiles/Java/jdk1.6.0_02(等号前面代表变量名,后来表示值,这样详细的解释感觉自己智商在下降~~后边的是你的jdk的安装位置,如果你的jdk1.6安装的时候默认的话,那么就这样设置就行了,不是的话相应改变);

 

Path加上一句(!!!注意是加上,不是把原来的东西给去掉,那么的话很多程序就不能运行了,然过你去掉了的话跟我联系,)%JAVA_HOME%/bin

Classpath=.;%JAVA_HOME%/lib/tools.jar;另外一点就是最好把你放置自己写的程序的位置也加进来。例如你平常程序都放在d:/source下,那么直接加上就可以了,别忘了分号~~~

 

Java入门基础(1)--java概念,环境变量配置,工作原理

编程 2009-09-10 18:47:45 阅读159 评论0  字号: 订阅

1.Java Edition:

   a.J2SE:Java Standard Edition 标准版

   b.J2EE:Java Enterprise Edition 企业版(商用)

   c.J2ME:Java Micro Edition 微缩版(手机,家电)

2.Java的相关概念:

 Java--sun开发(Sun的全称:Stanford university netlab,斯坦福大学网络实验室)

   a.JDK: Java Development Kit   java开发工具包

   b.JRE: Java Runtime Environment  java运行环境

   c.JVM: Java Virtual Machine  java虚拟机

   d.API:  Application Program Interface 应用程序接口(类库说明书)

   e.IDE: Integration Development Enviroment 集成开发环境

   f.GC:Garbage Collection 内存垃圾的回收

3.配置环境变量:(安装JDK后需要配置环境变量)

  PATH: 操作系统自带的环境变量,用来保存操作系统执行命令时的搜索

             配置所有目录通用可执行文件

            path变量的含义就是系统在任何路径下都可以识别java命令

            C:/Program Files/Java/jdk1.6.0_1/bin;  (bin里面是可执行文件)

  CLASSPATH: 系统搜索类的字节码文件时的搜索路径

             .class文件所在目录

             classpath,该变量的含义是为java加载类(class or lib)路径,只有类在classpath中,java命令才能识别

             C:/ProgramFiles/Java/jdk1.6.0_1/lib  (lib里面是类库)

  JAVA_HOME:用来保存JDK的安装路径,该变量不会被java的虚拟机读取,它为第三方软件提供寻找JDK的路径

            jdk的安装路径(第三方软件会引用约定好的JAVA_HOME变量,)不然, 你将不能正常使用该软件要是某个软件不能正常使用,不妨想想是不是这个问题.

            C:/Program Files/Java/jdk1.6.0_1

  a.Windows 配置:

    右键右击我的电脑--属性--高级--环境变量

    PATH配置: 选用户变量或者系统变量其一配置path找到以后选编辑(不要新建),不要删除path中原来的东西,而是在path最前边加上bin的目录,C:/ProgramFiles/Java/jdk1.6.0_1/bin; ;分隔其他目录

    CLASSPATH配置:点击新建,变量名写CLASSPATH,变量填写:.;C:/Program Files/Java/jdk1.6.0_1/lib;

    . 代表当前目录

   JAVA_HOME配置:点击新建,变量名写JAVA_HOME,变量填写:C:/Program Files/Java/jdk1.6.0_1

  b. Linux/Unix配置:

      改配置文件,当前用户

      vi /home/soft01/.bash_profile 在文件在最后加上:

      PATH =/opt/jdk1.6.0_1/bin:$PATH

      CLASSPATH =.:/opt/jdk1.6.0_1/lib

      JAVA_HOME = /opt/jdk1.6.0_1

      export  PATH CLASSPATH  JAVA_HOME

    说明::用来分隔路径

              $PATH 用来引用原来环境变量的值

              export是把这三个变量导出为全局变量。

  注意:配置完成后,Windows重启dos生效,Linux/Unixsource . bash_Profile一下

  验证:javac,或者java -version,如果安装成功,系统会显示javaversion jdk"1.6.0"

  说明:安装JDK后,JRE就有了,JRE = JVM+类库(代码库)

4.java源代码--->编译--->加载及运行工作原理:

  a.源文件通过编译命令编译成字节码文件(.class)

  b.类装载器将字节码从磁盘或网络中装入内存中

  c.字节码校验器保证所有的字节都是合法的,且没有违背Java的安全限制(不是100%的没问题)

  d.解释器读入字节码并将它们翻译成计算机能理解的语言

5.JVM的作用:

  a.使Java语言能够实现跨平台

  b.Java内存管理,内存释放自行解决

6.GCGarbageCollection  垃圾回收

  本质:JVM启动了一个后台线程

  内存管理:内存申请(),内存释放()

  Java--->JVM--->管理内存:申请(new),释放(自行解决)--->GC(垃圾回收)

  GC对内存垃圾回收:栈不存在垃圾回收,GC针对堆,如果栈中指向a断开,则堆中的bc都为内存垃圾

      a--->b--->c

  例如:a.Emp e = newEmp();

                       e= null;

               表明e虽然没有出栈,但是为null,此时对象可以垃圾回收

            b.Emp e = new Emp();

                       e = new Emp();

               表明e指向别的对象,与先前的指向已断开,可对先前的Emp对象垃圾回收

   作为程序员,对GC(垃圾回收)只有建议权,但决定权在JVM,建议回收垃圾:

        System.gc();

         Runtime.gc();

    finalize() 方法:Java技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。一般的纯Java编写的Class不需要重新覆盖这个方法,因为Object已经实现了一个默认的,除非我们要实现特殊的功能

    finalize()的工作原理:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.

    finalize()在什么时候被调用?
    
有三种情况
       1.
所有对象被GarbageCollection时自动调用,比如运行System.gc()的时候.
       2.
程序退出时为每个对象调用一次finalize方法。
       3.
显式的调用finalize方法

    除此以外,正常情况下,当某个对象被系统收集为无用信息的时候,finalize()将被自动调用,但是jvm不保证finalize()一定被调用,也就是说,finalize()的调用是不确定的,这也就是为什么sun不提倡使用finalize()的原因

7.Java语言的优点,缺点
  
优点:面向对象,简单、安全、稳定、跨平台
  
缺点:需要运行环境、不适合开发桌面应用程序
  
应用:BS结构的ERP系统、金融系统、电子商务系统、网站等

8.java为什么是跨平台的?

  因为Java由源代码编译的字节码是运行在JVM上的,JVM会根据不同的系统解释字节码为该系统可执行的机械语言,从而达到同一源代码不同系统的相同效果,实现跨平台。

9.Java是怎么管理内存的?

  java是通过JVM来实现内存的管理,内存的申请是通过关键字new来实现的,而内存的释放是由JVM通过GC(垃圾回收)自行解决的。

10.Java的第一个HelloWorld程序

  package day01;

  public class MyFirstJava {
      public static void main(String[] args){
       System.out.println("HelloWorld!");
      }
  }

说明:public的类,类名要和文件名相同,非public的类,类名和文件名可以不同

          一个.java文件可以写多个类,但是只有一个public类,编译是根据类名编译的

         package:为.class文件分目录

                           只能有一个package,必须放在第一行

                           包名最好全小写

                          . 可以分层目录

=========================================================================

摘自:百度百科

简介

JRE为JavaRunTimeEnvironment的简称,JavaRuntimeEnvironment(包括JavaPlug-in)是Sun的产品,包括两部分:JavaRuntimeEnvironment和JavaPlug-in。JavaRuntimeEnvironment(JRE)是可以在其上运行、测试和传输应用程序的Java平台。它包括Java虚拟机、Java平台核心类和支持文件。它不包含开发工具--编译器、调试器和其它工具JRE需要辅助软件--JavaPlug-in--以便在浏览器中运行applet

 

版本管理

  Java的解决办法是每个程序自己携带一套JRE。  比如说某人的机器上已经被安装了好多套JRE和JDK(JDK包括了同版本的JRE,此外还包括有编译器和其它工具),它们分别是:  BEA Weblogic Server 7.0 自带一套 JDK1.3.1_02, 还下载了一套最新的JDK1.4.1_02  JBuilder9自带一套JDK1.4.1_02  Oracle8.1.7自带一套JRE1.1.7  Ration Rose自带一套JDK1.3  DreamWeaver自带一套JDK1.3  6套JRE,每套JRE都被各自安装到不同的目录,不会互相影响。当在控制台执行java.exe,操作系统寻找JRE的方式如下:  先找当前目录下有没有JRE  再找父目录下有没有JRE  接着在PATH路径中找JRE  注册表HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Runtime Environment/ 查看CurrentVersion的键值指向哪个JRE

  最常用的是在PATH路径中找JRE,一般情况下,自己的程序运行之前都会先在批处理文件里面临时设置PATH,把自己用的JRE放到PATH路径最前面,所以肯定会运行自己带的JRE,不会造成版本混乱。

 

基础类库

       JRE自带的基础类库主要是JRE/lib/rt.jar这个文件,包括了Java2平台标准版的所有类库。和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参数指定路径的类库。因此Java的版本管理是非常简单有效的,也许很原始,不过很好用,简单就不容易出错。(所以我很奇怪Eric Ramond为什么批评Java的类库管理机制,他还居然批评Java的接口,令人怀疑他对Java的了解程度)

=========================================================================

大家肯定在安装JDK的时候会有选择是否安装单独的jre,一般都会一起安装,我也建议大家这样做。
因为这样更能帮助大家弄清楚它们的区别:

 Jre   是java   runtime   environment,   是java程序的运行环境。既然是运行,当然要包含jvm,也就是大家熟悉的虚拟机啦,还有所有java类库的class文件,都在lib目录下打包成了jar。大家可以自己验证。至于在windows上的虚拟机是哪个文件呢?   学过MFC的都知道什么是dll文件吧,那么大家看看jre/bin/client里面是不是有一个jvm.dll呢?那就是虚拟机。

 Jdk   是java   development   kit,是java的开发工具包,里面包含了各种类库和工具。当然也包括了另外一个Jre.     那么为什么要包括另外一个Jre呢?而且jdk/jre/bin同时有client和server两个文件夹下都包含一个jvm.dll。   说明是有两个虚拟机的。这一点不知道大家是否注意到了呢?

 相信大家都知道jdk的bin下有各种java程序需要用到的命令,与jre的bin目录最明显的区别就是jdk下才有javac,这一点很好理解,因为 jre只是一个运行环境而已。与开发无关,正因为如此,具备开发功能的jdk自己的jre下才会同时有client性质的jvm和server性质的 jvm,   而仅仅作为运行环境的jre下只需要client性质的jvm.dll就够了。

 记得在环境变量path中设置jdk/bin路径麽?这应该是大家学习Java的第一步吧,   老师会告诉大家不设置的话javac和java是用不了的。确实jdk/bin目录下包含了所有的命令。可是有没有人想过我们用的java命令并不是 jdk/bin目录下的而是jre/bin目录下的呢?不信可以做一个实验,大家可以把jdk/bin目录下的java.exe剪切到别的地方再运行 java程序,发现了什么?一切OK!

 那么有人会问了?我明明没有设置jre/bin目录到环境变量中啊?

 试想一下如果java为了提供给大多数人使用,他们是不需要jdk做开发的,只需要jre能让java程序跑起来就可以了,那么每个客户还需要手动去设置环境变量多麻烦啊?所以安装jre的时候安装程序自动帮你把jre的java.exe添加到了系统变量中,验证的方法很简单,大家看到了系统环境变量的 path最前面有“%SystemRoot%/system32;%SystemRoot%;”这样的配置,那么再去Windows/system32下面去看看吧,发现了什么?有一个java.exe。

 如果强行能够把jdk/bin挪到system32变量前面,当然也可以迫使使用jdk/jre里面的java,不过除非有必要,我不建议大家这么做。使用单独的jre跑java程序也算是客户环境下的一种测试。

这下大家应该更清楚jdk和jre内部的一些联系和区别了吧?

PS:   其实还有满多感想可以总结的,一次写多了怕大家扔砖头砸死我,怪我太罗唆。大家应该更加踏实更加务实的去做一些研究并互相分享心得,大方向和太前沿的技术讨论是必要的但最好不要太多,毕竟自己基础都还没打好,什么都讲最新版本其实是进步的一大障碍!

=================================================================================

JVM之所以能实现跨平台是因为其起到了调用操作系统API将资源分给应用程序的作用,这样应用程序就能摆脱对操作系统API不同的依赖了,但是对操作系统API的调用不是无偿的,是需要一定运行环境支持的,JRE就提供了需要的环境,没有JRE,JVM无法调用操作系统API,应用程序得不到本地资源无法运行