一、测试的pojo
public class Student {
private Stringname;
int age;
public Stringaddress;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name =name;
this.age =age;
}
public Student(String name, int age, Stringaddress) {
super();
this.name =name;
this.age =age;
this.address =address;
}
public void show(Stringstr){
System.out.println(str+"是好孩子!");
}
@Override
public String toString() {
return"Student [name=" + name +", age=" + age +", address=" + address +"]";
}
}
二、加载字节码对象的方式
public class TestMain {
/**
* 获取字节码的方式
* 1. 对象.getClass();
* 2.类名.class
* 3. Class.forName( String str)
*/
//自己:类名.class
//项目: 第三种
public static void main(String[]args) throws Exception {
Student stu1=new Student();
Class c1= stu1.getClass();
Student stu2=new Student();
Class cc1= stu2.getClass();
System.out.println(stu1==stu2);//false 不是同一对象,内存空间不同
System.out.println(c1==cc1);//true
Class c2=Student.class;
System.out.println(c1==c2);//true 同一份字节码
Class c3=Class.forName("com.lanou.reflect.Student");//包名+类名
System.out.println(c2==c3);
}
}
三、构造方法反射
package com.lanou.reflect;
import java.lang.reflect.Constructor;
public class TestConstract {
/**
* 反射就是把Java类中的各种成分映射成相应的Java类
* 通过字节码文件对象,去使用成员变量,构造方法,成员方法
* 成员变量:Field
* 构造方法 :Constructor
* 成员方法:Method
*/
public static void main(String[]args) throws Exception {
// 通过反射拿到字节码的对象
Class c = Class.forName("com.lanou.reflect.Student");
//c.getConstructors() 不返回有私有成员变量的方法,所有公有的变量
// 拿到字节码的构造方法对象,通过参数确定构造方法,参数是Class类型
Constructor con = c.getConstructor( String.class,int.class,String.class);
//通过构造方法对象拿到类的对象
Object obj=con.newInstance("于飞",21,"兰州");//obj是的类型取决于拿到那个类的字节码
System.out.println(obj);
}
}
四、成员变量反射package com.lanou.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/*
* people p=new People();
* p.setAddress("深圳");
*/
public class FieldTest {
// 通过反射获取成员变量
public static void main(String[]args) throws Exception {
// 获取字节码对象
Class c = Class.forName("com.lanou.reflect.Student");
// Field[] field=c.getFields();//获取公共的成员变量
// Field[] field = c.getDeclaredFields(); // 获取所有的成员变量
// for (Field field2 : field) {
// System.out.println(field2);
// }
// 通过无参构造方法创建没对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
System.out.println(obj);
// 获取单个的成员变量
Field addressField =c.getField("address");
// 将指定对象上此Field对象表示的字段设定为指定的新值
addressField.set(obj,"深圳");// 给obj对象的address字段设置值为深圳
System.out.println(obj);
//获取name属性,并赋值
Field nameField=c.getDeclaredField("name");//因为私有必须加declared,通用方法
nameField.setAccessible(true);//强制访问,必须用的方法
nameField.set(obj,"yufei");
System.out.println(obj);
//获取age并赋值
Field ageField=c.getDeclaredField("age");
ageField.setAccessible(true);
ageField.set(obj, 21);
System.out.println(obj);
}
}
五、成员方法的反射package com.lanou.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class MethodTest {
public static void main(String[]args) throws Exception, Exception, Exception {
// 获取字节码对象
Class c = Class.forName("com.lanou.reflect.Student");
// Method[] method= c.getMethods();//获取自己的和父类的方法
// Method[] method = c.getDeclaredMethods();// 只获取自己的方法
// for (Method method2 : method) {
// System.out.println(method2);
// }
// 获得对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 以下常用:获取单个方法并使用
// 方法名称,参数类型,字节码型
Method m1 = c.getMethod("show", String.class);
// 返回值是Object,第一个参数表示对象是谁,第二个参数表示方法的实际参数
m1.invoke(obj,"yufei");//相当于调用obj对象的m1方法
//被private 修饰的 方法用getDeclaredMethod(name, parameterTypes)方法,在设置强制访问
}
}