1. Java简介
产生原因:
Sun公司的,来自于一个叫Green的项目,其项目设计目的是为开发一个分布式代码系统。
C++过于复杂,其安全性差。
决定基于C++开发一个新语言,Oak(java前身)。
Java 主设计者 James Gosling
Java的3个发展方向:
1> J2SE:Java 2 Platform Standard Edition
标准版,即Java的核心类。
如数据库链接,接口定义,输入/输出和网络编程。
2> J2ME:Java 2 Platform Micro Edition
微型版,包含J2SE的一部分类,主要用于消费类电子产品的软件开发。
如寻呼机、智能卡、手机、PDA和机顶盒等。
3> J2EE:Java 2 Platform Enterprise Edition
企业版,包含J2SE的所有类,并且还含有用于开发企业级应用的类。
如EJB、Servlet、JSP、XML和Transaction等,这也是Java应用的主要方向。
2. Java 与 C 的 核心区别
1> Java 面向对象的
C 面向过程的
2> Java 解释型语言
C 编译式语言
3> Java 由于JVM的存在,具有跨平台特性,但也正是因为JVM的存在,使得其程序效率低,执行缓慢。
C 不可移植性,程序执行效率高。
4> Java 安全性高(封装性),多线程优秀。
C 安全性较差
5> 还有很多区别。
3. 编译机制
.java --> JRE --> 编译 --> .class --> JVM --> 解释 --> 二进制序列(0,1) -->运行
.class 文件:
与平台无关的字节码文件,
class文件是由Java编译器将编写的*.java源文件,编译成二进制字节码文件而成的,这种文件可以在不同的JVM上执行。
可以对比一下: C是针对系统的编译,不同系统不同需要有代码
Java是针对JVM的编译,不同的JVM可以执行同一class,JVM再转换代码执行在系统中。
JVM加载class文件的原理:
1>Java中的所有类,必须被装载到JVM中才能运行。
这个装载工作是由JVM中的 类装载器完成的, 类装载器所做的工作实质是把类文件从硬盘读取到内存中。
2> Java中类大致分三种:
系统类 ---- 如 J2SE 中的类
扩展类 ---- 如 引入的jar包的类
由程序员自定义类 ---- 程序员自己编写的类
3> 类装载方式:
隐式装载: 程序在运行过程中当碰到通过new等方式生成对象时, 隐式调用类装载器加载对应的类到JVM中
显式装载: 通过class.forname()等方法,显式加载需要的类。
两者本质是一样的
4> 类加载的动态性体现
Java程序启动时,并不是一次性把所有类全部加载再运行,
它总是先把保证程序运行的基础类一次性加载到JVM中,其它的类等到JVM用到的时候再加载,这样的好处是节省了内存的开销。
5> Java类装载器
Java中的类装载器实质上也是 类
功能是把类载入JVM中
JVM的类装载器并不是一个,而是三个:
Bootstrap Loader - 负责加载系统类
|
- - ExtClassLoader - 负责加载扩展类
|
- - AppClassLoader - 负责加载应用类
一方面是分工,各自负责加载各自的类
另一方面是为了实现 委托模型。
6> 类装载器工作原理:
Java 对于类装载器采用了 委托模型机制,即是:
类装载其有载入类需求时,会先请示 其Parent 使用其搜索路径帮忙载入,
如果Parent找不到,那么才由自己依照自己的搜索路径搜索类。
/**
* @author Jamson Huang
*
*/
public class TestClass {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
//调用class加载器
ClassLoader cl = TestClass.class.getClassLoader();
System.out.println(cl);
//调用上一层Class加载器
ClassLoader clParent = cl.getParent();
System.out.println(clParent);
//调用根部Class加载器
ClassLoader clRoot = clParent.getParent();
System.out.println(clRoot);
}
}
1 Result代码 收藏代码
2
3 Run, Console中出现的log信息如下:
4 sun.misc.Launcher$AppClassLoader@7259da
5 sun.misc.Launcher$ExtClassLoader@16930e2
6 null
Testclass 是由AppclassLoader加载器加载的
AppClassLoader 的 Parent 加载器是ExtClassLoader
ExtClassLoader 的 Parent 加载器是BootStrapLoader,这里显示为null
因为BootStrap Loader是C++语言写的, 依Java逻辑不存在 其类实体,所以为null
7> 预先加载(pre-loading) 和 依需求加载(load-on-demand)
Java运行环境为了优化系统,提高程序的执行速度,在JRE运行的开始会将Java运行所需要的基本类采用 pre-loading 的方式全部加载到内存当中, 因为这些单元在Java程序的运行过程中经常使用,
主要包括: JRE的 rt.jar 文件中的所有 .class文件
当java.exe虚拟机开始运行以后,它会找到安装在机器上的JRE环境,然后将控制权交给JRE,JRE的类加载器会将lib目录下的rt.jar 基础类别文件库加载入内存,这些文件是Java程序执行所必须的,所以系统在开始就将这些文件加载,避免以后的多次IO操作,从而提高程序执行效率。
8> 类加载器的层次体系
当执行 *.class 文件时, Java.exe会找到JRE
接着找到JRE内部的jvm.dll,这才是真正的Java虚拟机(JVM),最后加载动态库,激活JVM
JVM激活后,会先做一些初始化的动作,比如 读取系统参数等。
初始化完成后,产生第一个类加载器: BootstrapLoader
BootStrapLoader 是C++编写而成的,其中除了一些基本的初始化工作外,
最重要的是加载Launcher.java 中的ExtClassLoader , 并设定其Parent为null
然后BootStrapLoader再要求加载Laucher.java中的AppClassLoader
并设定其Parent为之前产生的ExtClassLoader的实体。
这两个类加载器都是以静态类的形式存在的
三者关系如下: BootstrapLoader <---(Extends)----AppClassLoader <---(Extends)----ExtClassLoader
这三个加载器就构成我们的 Java 类加载体系。他们分别从以下的路径寻找程序所需要的类:
BootstrapLoader : sun.boot.class.path
ExtClassLoader: java.ext.dirs
AppClassLoader: java.class.path
这三个系统参量可以通过 System.getProperty() 函数得到具体对应的路径。