1、编译和运行概念要搞清:编译即javac的过程,负责将.java文件compile成.class文件,主要是类型、格式检查与编译成字节码文件,而加载是指java *的过程,将.class文件加载到内存中去解释执行,即运行的时候才会有加载一说。
2、类的加载时机,肯定是在运行时,但并不是一次性全部加载,而是按需动态,依靠反射来实现动态加载,一般来说一个class只会被加载一次,之后就会从jvm的class实例的缓存中获取,谁用谁取就可以了,不会再去文件系统中加载.class文件了。
Java
Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
package my
import java.io.File
import java.io.IOException
import java.net.URL
public class MyUrlDemo {
public static void main(String[] args) {
MyUrlDemo muDemo = new MyUrlDemo()
try {
muDemo.showURL()
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace()
}
} public void showURL() throws IOException {
// 第一种:获取类加载的根路径 D:\git\daotie\daotie\target\classes
File f = new File(this.getClass().getResource("/").getPath())
System.out.println(f)
// 获取当前类的所在工程路径 如果不加“/” 获取当前类的加载目录 D:\git\daotie\daotie\target\classes\my
File f2 = new File(this.getClass().getResource("").getPath())
System.out.println(f2)
// 第二种:获取项目路径 D:\git\daotie\daotie
File directory = new File("")// 参数为空
String courseFile = directory.getCanonicalPath()
System.out.println(courseFile)
// 第三种: file:/D:/git/daotie/daotie/target/classes/
URL xmlpath = this.getClass().getClassLoader().getResource("")
System.out.println(xmlpath)
// 第四种: D:\git\daotie\daotie
System.out.println(System.getProperty("user.dir"))
/*
* 结果: C:\Documents and Settings\Administrator\workspace\projectName
* 获取当前工程路径
*/
// 第五种: 获取所有的类路径 包括jar包的路径
System.out.println(System.getProperty("java.class.path"))
}
}
首先,"java的类在第一次需要创建类的实例(对象)时被加载"这个说的不对\x0d\x0a\x0d\x0ajava中类被使用就就会时就会被加载到内存(比如反射等)\x0d\x0a然后回答你的问题。\x0d\x0a\x0d\x0a首先要介绍下相关知识(基础知识纯属拷贝):\x0d\x0a\x0d\x0a首先来了解一下jvm(java虚拟机)中的几个比较重要的内存区域\x0d\x0a\x0d\x0a方法区:在java的虚拟机中有一块专门用来存放已经加载的类信息、常量、静态变量以及方法代码的内存区域,叫做方法区。\x0d\x0a常量池:常量池是方法区的一部分,主要用来存放常量和类中的符号引用等信息。\x0d\x0a堆区:用于存放类的对象实例。\x0d\x0a栈区:也叫java虚拟机栈,是由一个一个的栈帧组成的后进先出的栈式结构,栈桢中存放方法运行时产生的局部变量、方法出口等信息。当调用一个方法时,虚拟机栈中就会创建一个栈帧存放这些数据,当方法调用完成时,栈帧消失,如果方法中调用了其他方法,则继续在栈顶创建新的栈桢。\x0d\x0a除了以上四个内存区域之外,jvm中的运行时内存区域还包括本地方法栈和程序计数器,这两个区域与java类的生命周期关系不是很大,在这里就不说了,感兴趣可以自己百度一下。\x0d\x0a\x0d\x0a其实类在JVM里面有以下几个阶段:\x0d\x0a\x0d\x0a加载 -- 连接 -- 初始化 -- 使用 -- 卸载 \x0d\x0a\x0d\x0a主要给你说明卸载:\x0d\x0a在类使用完之后可能会被卸载,可能性如下:\x0d\x0a如果有下面的情况,类就会被卸载:\x0d\x0a该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。\x0d\x0a加载该类的ClassLoader已经被回收。\x0d\x0a该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。\x0d\x0a如果以上三个条件全部满足,jvm就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程其实就是在方法区中清空类信息,java类的整个生命周期就结束了。