反射:反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够用它的任意一个方法和属性,这种动态获取信息以及动态调用对象的方法的功能就是java中的反射机制 要想解剖一个类,必须先要获取到该类的字节码文件对象,而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象
下面就是具体的代码实现
通过反射来获取某个类中的构造方法,普通方法,属性
下面数代码的实现,注释中详细写明了得到构造方法,普通方法,属性,的具体步骤
1.普通类:
package cn.kgc.reflect;
/**
* 实体用户类
* @author 92126
*
*/
public class User {
//Filed 访问修饰符 数据类型 属性值 属性名....
private String name = "1111";
public int age=2222;
private User(int age) {
this.age = age;
System.out.println("(私有)带参构造2正在执行!");
}
//Constructor(构造方法)访问修饰符 构造名 构造参数信息
public User() {
System.out.println("无参构造正在执行");
}
public User(String name) {
this.name = name;
System.out.println("带参构造正在执行1"+name);
}
//Mehtod方法
public void print1() {
System.out.println("普通方法1"+name);
}
public void print2(String msg) {
System.out.println("普通方法2"+msg);
}
public String getName() {
return "普通方法3";
}
private int print3(int xx) {
return xx;
}
}
2.通过反射来获取某个类中的构造方法
package cn.kgc.reflect;
import java.lang.reflect.Constructor;
/**通过 反射操作来操纵某个类
* @author 92126
*
*/
public class ConstructorUser {
public static void main(String[] args) throws Exception {
//1.获取字节码对象
//Class<?> name = Class.forName("cn.kgc.reflect.User");
/*//2.获取此类的所有的公共构造方法
Constructor<?>[] constructors = name.getConstructors();
//3.获取所有的的公共的构造,包含私有的
Constructor<?>[] declaredConstructors = name.getDeclaredConstructors();
//4.获取此类中指定构造
//5.获取公共的无参的
Constructor<?>[] constructors2 = name.getConstructors();
//6.获取私有带参
Constructor<?> declaredConstructor = name.getDeclaredConstructor(int.class);*/
//7.使用无参构造创造对象
//User newInstance = (User) name.newInstance();
//8.使用私有构造创建对象
Class<?> name = Class.forName("cn.kgc.reflect.User");
Constructor<?> name1 = name.getDeclaredConstructor(int.class);
name1.setAccessible(true);
User newInstance = (User) name1.newInstance(10);
newInstance.print2("020");
}
}
3.通过反射获取某个类中的普通的方法
package cn.kgc.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* 通过反射获取某个类中的普通的方法
* @author 92126
*
*/
public class MothodTest {
public static void main(String[] args) throws Exception {
//1.获取字节码对象
Class<?> demo = Class.forName("cn.kgc.reflect.User");
//2.使用获取的字节码对象快速创建对象
User dome1 = (User) demo.newInstance();
//3.通过字节码对象来获取此类中的公共的方法
Constructor[] demo2 = demo.getDeclaredConstructors();
//4.通过字节码对象来获取此类的所有普通的方法,包括私有的方法
Constructor[] demo3 = demo.getDeclaredConstructors();
//5.获取指定的普通的方法
//p1:方法名 p2:参数列表的字节码类型的可变参数
Method method = demo.getMethod("print2", String.class);
//6.获取指定的私有的普通的方法
Method method2 = demo.getDeclaredMethod("print3", int.class);
//7.执行指定普通的方法
//p1:谁要执行 p2:调用方法传递的参数
//返回的是方法执行后的结果,该方法如果没有返回值,则返回null;
Object invoke = method.invoke(dome1, "老师");
//8.执行私有的方法
//暴力反射
method2.setAccessible(true);
Object invoke2 = method2.invoke(dome1, 13);
System.out.println(invoke2);
}
}
4.通过反射来获取某个类中的字段
package cn.kgc.reflect;
import java.lang.reflect.Field;
/**
* 通过反射来操作此类中的某个属性
* @author 92126
*
*/
public class FiledTest {
public static void main(String[] args) throws Exception {
//1.创建字节码对象
Class<?> demo = Class.forName("cn.kgc.reflect.User");
/*//2.通过字节码文件来获取此类中的public的属性
Field[] fields = demo.getFields();
//3.通过字节码对象来获取此类中的所有属性包括私有的
Field[] fields2 = demo.getDeclaredFields();*/
//4.获取指定的属性
/* Field field = demo.getField("age");
//获取值get(param) param:表示从。。对象中的此字段获取值
System.out.println( field.get(demo));*/
//5.获取指定的私有的属性
Field field2 = demo.getDeclaredField("name");
/*//通过暴力反射是无反获取到私有的属性的值的
field2.setAccessible(true);
System.out.println(field2.get(demo));*/
//设置属性值
field2.set(demo, "12315");
System.out.println(field2.get(demo));
}
}
5.获取字节码对象的三种方法
package cn.kgc.reflect;
/**
* 反射第一步:获取要操作类的字节码对象(class)
* @author 92126
*获取字节码对象的三种方法
*/
public class ClassTest {
public static void main(String[] args) throws ClassNotFoundException {
//1.通过类名来获取字节码对象
Class clazz = User.class;
//2.通过实例来获取字节码对象
/**
* new一个想要操作的类,来得到他的字节码对象
*
*/
User user = new User();
Class class1 = user.getClass();
//3.通过全类名获取字节码对象
Class<?> forName = Class.forName("cn.kgc.reflect.User");
}
}