1.类加载器:程序加载某个类时,若类不在内存中,就会通过加载连接初始化三部实现对类的初始化。
加载:将class文件读入内存并为之创建一个Class对象
链接:验证内部结构,为静态成员分配内存,设置默认初始化值,将类的二进制数据符号引用替换为直接引用
初始化:为变量赋初值
2.类的加载时机:A:创建类的实例 B:访问类的静态变量或为静态变量赋值 C:调用类的静态方法
D:使用反射方式强制创建类或接口的java.lang.Class对象 E:初始化某个类的子类
F:直接使用java.exe命令来运行某个主类
3.加载器分类:A:Bootstrap ClassLoader 根类加载器,负责java核心类的加载,在JDK中JRE的lib目录下rt.jar文件中
B:Extension ClassLoader 扩展类加载器,负责JRE扩展类jre包的加载,在JDK中JRE的lib目录下ext
目录
C:Sysetm ClassLoader 系统类加载器,负责JVM启动时来自java程序的Class文件
4.反射:通过字节码文件去使用成员的过程该文件为类名.class文件
获取文件对象的方式:A:Object类的getClass()方法
B:数据类型的静态class属性
C:Class类的静态方法forName()
package Reflect;
public class Demo1 {
public static void main(String[] args) throws Exception {
Person p1=new Person();
Class c1=p1.getClass();//Object类的getClass()方法
Class c2=Person.class;//数据类型的静态class属性
Class c3=Class.forName("Reflect.Person");//C:Class类的静态方法forName()
System.out.println(c1.getName());//Reflect.Person
System.out.println(c2.getName());//Reflect.Person
System.out.println(c3.getName());//Reflect.Person
}
}
一般直接使用第二种最方便,但第三种可以把参数作为配置文件的内容
5.反射的使用步骤:成员变量Field,构造方法 Constructor,成员方法 Method,用class字节码文件对象得到对应的成
员对象,在通过该成员对象调用方法使用
6.通过反射获取构造方法:
A:public Constructor[] getConstructors() 获取公共的构造方法
ublic Constructor[] getDeclaredConstructors() 获取所有的构造方法(包括私有)
B:public Constructor getConstructor(Class... parameterTypes) 根据构造参数获取公共的指定构造
public Constructor getDeclaredConstructor(Class<?>... parameterTypes) 根据构造参数获取指定构造(包括私
有,但是私有在使用的时候需要取消访问限制)
public class Person {
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
exp:通过反射获取构造方法并创建对象
import java.lang.reflect.Constructor;
public class Demo2 {
public static void main(String[] args) throws Exception {
Constructor[] p=Person.class.getConstructors();
Constructor p2=Person.class.getDeclaredConstructor(String.class,int.class);
for (Constructor c : p) {
System.out.println(c);//获取所有构造方法
}
p2.setAccessible(true);//取消访问限制
Object obj=p2.newInstance("a",1);//利用反射创建对象
System.out.println(obj);
}
}
7.通过反射获取成员变量并使用
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/*
* public Field[] getFields()获取公有的成员变量
public Field[] getDeclaredFields()获取全部的成员变量,包括私有
public Field getDeclaredField(String name) 传入变量名称返回指定的成员变量对象,包括私有
public Field getField(String name)传入变量名称返回指定的成员变量对象,仅可获取共有的
public void set(Object obj,Object value) 给一个对象的一个字段设置一个值
*/
public class Demo3 {
public static void main(String[] args) throws Exception {
Class c=Class.forName("Reflect.Person");
Constructor con=c.getDeclaredConstructor();
Object obj=con.newInstance();//通过反射创建对象
Field[] f=c.getDeclaredFields();//获取全部变量(包括私有)
for (Field field : f) {//增强for遍历获取的变量
System.out.println(field);
}
Field f1=c.getDeclaredField("name");//反射获取变量
Field f2=c.getDeclaredField("age");
f1.setAccessible(true);//取消检测
f2.setAccessible(true);
f1.set(obj,"a");//通过反射给变量赋值
f2.set(obj, 1);
System.out.println(obj);
}
}
8.通过反射获取成员方法并使用
/*public Method[] getMethods()获取所有公共成员方法
public Method[] getDeclaredMethods()获取所有成员方法,包括私有
public Method getMethod(String name, Class<?>... parameterTypes)参数一:方法名 参数二:方法参数类型.class 获取指定的公共方法
public Method getDeclaredMethod(String name,Class<?>... parameterTypes)参数一:方法名 参数二:方法参数类型.class 获取指定的方法,包括私有
Object invoke(Object obj, Object... args) 让某一个对象使用这个方法,并且传入参数
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Demo4 {
public static void main(String[] args) throws Exception {
Class c=Class.forName("Reflect.Person");
Constructor con=c.getConstructor();//反射创建对象
Object obj=con.newInstance();
Method [] m=c.getDeclaredMethods();//反射获取成员方法
for (Method method : m) {
System.out.println(method);
}
Method m1=c.getDeclaredMethod("setName",String.class);//使用方法
Method m2=c.getDeclaredMethod("getName");
m1.invoke(obj, "a");
m2.invoke(obj);
System.out.println(obj);
}
}