异常错误java
Java.lang.ClassNotFoundExcetpion背后就涉及到了java技术体系中的类加载编程
概念数组
- 元信息: Class文件由类装载器装载后,在JVM中将造成一份描述Class结构的元信息对象,经过该元信息对象能够获知Class的结构信息:如构造函数,属性和方法等,Java容许用户借由这个Class相关的元信息对象间接调用Class对象的功能
- 类加载机制:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终造成能够被虚拟机直接使用的Java类型
存在引用多线程
那么若是ClassA中引用了ClassB呢?当类加载器在加载ClassA的时候,发现引用了ClassB,此时类加载若是检测到ClassB尚未被加载,则先回去加载.当ClassB加载完成后,继续回来加载ClassA.换句话说,类会经过自身对应的来加载其加载其余引用的类.jvm
肯定类的惟一性函数
JVM规定,对于任何一个类,都须要由加载它的类加载器和这个类自己一同确立在java虚拟机中的惟一性,通俗点就是说,在jvm中判断两个类是不是同一个类取决于类加载和类自己,也就是同一个类加载器加载的同一份Class文件生成的Class对象才是相同的,类加载器不一样,那么这两个类必定不相同.this
class对象的理解.net
- 类只是对事物的描述,而实例化就至关于为这个描述新开辟了一块内存,能够改变这块区域里的各类属性(成员变量)
- 在java里,Class是一个实实在在的类,在包 java.lang 下,有这样一个Class.java文件,它跟咱们本身定义的类同样,是一个实实在在的类,Class对象就是这个Class类的实例了
- /*
- Constructor. Only the Java Virtual Machine creates Class
- objects. */ private Class() {}
- java.lang.Class类,这个类只能经过JVM来建立
- 在Java里,全部的类的根源都是Object类,而Class也不例外,它是继承自Object的一个特殊的类,它内部能够记录类的成员、接口等信息,也就是在Java里,Class是一个用来表示类的类,Class是一个实实在在的类,能够为它建立实例
- Class对象,也被叫作Class类的实例 例如运行的程序有A、B、C三个类,那么Class类就是对A、B、C三个类的抽象。所谓抽象,就是提取这些类的一些共同特征,好比说这些类都有类名,都有对应的hashcode,还有其余一些元数据
- 虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每一个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。若是没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。
- 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 每一个数组属于被映射为 Class 对象的一个类,全部具备相同元素类型和维数的数组都共享该 Class 对象
- 将某个类的class对象(描述这个类的类),而后将它载入到了内存中的时候,其他的全部的实例都是依照这个模版来建立的。总结起来:在运行期间,若是咱们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。若是没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就能够用它来产生该类型的全部对象
- Java程序在运行时每一个类都会对应一个Class对象,能够从Class对象中获得与类相关的信息,Class对象存储在方法区(又名Non-Heap,永久代),当咱们运行Java程序时,若是加载的jar包很是多,大于指定的永久代内存大小时,则会报出PermGen错误,就是Class对象的总计大小,超过永久代内存的缘故。
- 获取父类方法:getSuperclass() public native Class<? super T> getSuperclass(); 这是一个本地方法,这里的逻辑有点饶,方法返回的是这个Class对象所表明的Java类的父类对应的的Class 对象。 例如: Thread.class.getSuperclass()将返回一个表明Thread类的Class对象,Thread.class.getSuperclass().toString()则输出这个Class对象的字符串表示:classjava.lang.Object。其实这里的关系无非就是说Thread的超类是Object
取得class类,而后实例化线程
有一个表明java.lang.Thread类的Class实例对象objec1,也就是说,泛型参数T此时就是Thread,object1这个实例表明Thread这个类。好了,如今调用object1的newInstance方法,即object1.newInstance(),此时这个调用将返回一个Thread类的对象。简单验证:code
public class ForName {
/**
* @param args
* @throwsIllegalAccessException
* @throwsInstantiationException
*/
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
Class<?> c = null ;
try {
c = Class.forName("java.lang.Thread");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Thread thread = (Thread) c.newInstance(); //类型转化一下
System.out.println(thread.getId());
} }
9. class类的方法和技巧
- . 一个Class对象描述了一个特定类的属性,Class类中最经常使用的方法getName以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称
- . forName和newInstance结合起来使用,能够根据存储在字符串中的类名建立对象。例如 Object obj = Class.forName(s).newInstance();
- 虚拟机为每种类型管理一个独一无二的Class对象。所以可使用==操做符来比较类对象。例如: if(e.getClass() == Employee.class)...
java.lang包中的基础类库-object
- . Object没有实现clone(),实现了hashCode(),哈希就是对象实例化后在堆内存的地址,用“==”比较两个对象,实际就是比较的内存地址是不是一个,也就是hashCode()是否相等
- . 对象的equals()方法和==符号是同样的,都是比较内存地址,可是有些对象重写了equals()方法,好比String,使其达到比较内容是否相同的效果
- . 两个方法wait()和notify()是和多线程编程相关的,多线程里面synchronized实际就是加锁,默认是用this当锁,固然也能够用任何对象当锁,wait()上锁,线程阻塞,notify()开锁,收到这个通知的线程运行