java反射的讲解
1.什么是反射? 2,如何获取反射类 3.如果根据反射类获取类对象 4.如何获取类中属性对象 5,如何获取类中方法的对象 6.如何获取类中构造方法对象
1.什么是反射
Java反射是一种强大的机制,它允许程序在运行时动态地检查、访问和修改类、对象、方法和属性等相关信息。通过反射,我们可以在运行时获取类的完整结构,包括成员变量、方法、构造函数等,并且可以动态地调用或修改它们。
.java----通过javac编译---->>(字节码文件)----通过类加载器---->>(.class文件(jvm虚拟机中))
2.如何获取反射类
获取class类对象的三种方式:
第一种:Class.forName("类路径")
第二种:类名.class
第三种:对象.getClass
public class Test01 { public static void main(String[] args) throws ClassNotFoundException { //第一种:根据animal的类路径来获取animal的反射对象 Class<?> aClass = Class.forName("com.gll.date0810.Test.t1.Animal"); //第二种: 根据类名来获取animal类的反射对象 Class<Animal> animalClass = Animal.class; //第三种: 通过类对象来获取类的反射类的对象 Animal animal = new Animal(); Class<? extends Animal> aClass1 = animal.getClass(); System.out.println(aClass==animalClass); System.out.println(aClass==aClass1); } } @Data @NoArgsConstructor @AllArgsConstructor class Animal{ private String name; private String sex; }
3.如何根据反射类来获取类对象
通过class类对象,调用 newInstance()来获取类对象
//第二种: 根据类名来获取animal类的反射对象 Class<Animal> animalClass = Animal.class; //通过反射类来得到对应的类对象, --之前方式: new animal()来获取animal类的对象 Animal animal1 = animalClass.newInstance(); System.out.println(animal1);
4.如何获取反射类中属性成员对象
字节码中的属性成员被加载到内存中后会以Field对象的形式存在。如何获取Field属性对象。
getField(String name) :获取指定属性名的public属性对象
getFields() :获取所有的public 属性对象 包括父类中的属性;
getDeclaredField(String name) :获取指定属性类对象,不能获取包含父类的属性;
getDeclaredFields :获取所有的属性类对象,不包含父类的属性
public class Test02 { public static void main(String[] args) throws NoSuchFieldException { //1获取stadent类的反射类 Class<Student> studentClass = Student.class; //2获取反射类中的成员对象 Field[] declaredFields = studentClass.getDeclaredFields();//获取本类中所有的属性对象 for (Field declaredField : declaredFields) { System.out.println(declaredField); } System.out.println("------------分割线---------------"); Field[] fields = studentClass.getFields();//获取本类中和父类中public的属性对象 for (Field field : fields) { System.out.println(field); } System.out.println("----------分割线--------"); Field field = studentClass.getField("age");//获取指定属性名的public 属性对象 System.out.println(field); } } class People{ public String hand; private String foot; } @Data @NoArgsConstructor @AllArgsConstructor class Student extends People{ public String name; public int age; private int phone; String address; public void show(){ System.out.println("正在展示内容,"+name+","+age); } }
4.2 Field类中具有的常用方法
setAccessible(true) :设置允许访问私有属性 getAnnotation(注解.class) :获取属性上的注解对象
public class Test03 { public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException { //1获取反射类对象 Class<Dog> dogClass = Dog.class; //2通过反射类对象来获取类对象 Dog dog = dogClass.newInstance(); //得到反射类中的name属性对象 Field declaredField = dogClass.getDeclaredField("name"); declaredField.set(dog,"旺财");//通过name属性为Dog对象赋值 System.out.println(dog); //得到反射类中的age属性 Field declaredField1 = dogClass.getDeclaredField("age"); declaredField1.setAccessible(true); //允许访问私有属性 declaredField1.set(dog,12); System.out.println(dog); //获取属性上的注解对象 My annotation = declaredField.getAnnotation(My.class); System.out.println(annotation.value()); } } @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface My{ String value(); } @Data @NoArgsConstructor @AllArgsConstructor class Dog{ @My(value = "名字") public String name; private int age; }
5.获取Method方法类对象
getMethod(String name, 类<?>... parameterTypes) 得到指定名称和形参类型的方法 getMethods() :得到所有的public修饰方法。 getDeclaredMethod :根据名字获取本类中的方法 getDeclaredMethods :获取本类所有的方法
public class Test4 { public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException { //1获取反射类 Class<hello> helloClass = hello.class; //2通过反射类来获取类对象 hello hello = helloClass.newInstance(); //3通过反射类获取本类中所有的方法 Method[] declaredMethods = helloClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } //4获取本类及父类中public方法 Method[] methods = helloClass.getMethods(); for (Method method : methods) { System.out.println(method); } //5获取本类的指定方法 Method method = helloClass.getDeclaredMethod("h1", int.class); System.out.println(method); } } class hi{ public void h0(){ System.out.println("what's,up"); } } class hello extends hi{ public void h1(){ System.out.println("你好"); } public void h1(int h){ System.out.println("你好"); } public void h2(){ System.out.println("我好"); } private void h3(){ System.out.println("大家好"); } }
5.2 Method类中常用的方法
invoke:() 执行该方法体
getAnnotation() 获取该注解对象
public class Test4 { public static void main(String[] args){ //1获取反射类 Class<hello> helloClass = hello.class; //2通过反射类来获取类对象 hello hello = helloClass.newInstance(); //3通过反射类获取本类中所有的方法 Method[] declaredMethods = helloClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } //4获取本类及父类中public方法 Method[] methods = helloClass.getMethods(); for (Method method : methods) { System.out.println(method); } //5获取本类的指定方法 Method method = helloClass.getMethod("h1", int.class); Object invoke = method.invoke(hello, 888);//回调该方法 System.out.println("~~~~~~~~~~~~"+invoke); //获取注解对象 My annotation = method.getAnnotation(My.class); System.out.println(annotation.value()); } } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface My{ String value(); } class hi{ public void h0(){ System.out.println("what's,up"); } } class hello extends hi{ public void h1(){ System.out.println("你好"); } @My("dididi") public void h1(int h){ System.out.println("你好1"); } public void h2(){ System.out.println("我好"); } private void h3(){ System.out.println("大家好"); } }
6.如何获取类中构造方法对象
public Constructor<?>[] getConstructors() | 返回子类和父类public权限的构造函数的对象数组 |
---|---|
public Constructor<?>[] getDeclaredConstructors() | 获取本类所有构造函数方法,包括所有权限public,private,protected,default权限。 |
public Constructor getConstructor(Class... parameterTypes) | 获取单个public权限的构造方法。 |
---|---|
public Constructor getDeclaredConstructor(Class... parameterTypes) | 获取单个构造方法,包括所有权限public,private,protected,default权限。 |
public class Test5 { public static void main(String[] args) throws InstantiationException, IllegalAccessException { Class<Q> qClass = Q.class; Q q = qClass.newInstance(); • *//**返回本类中的所有构造 \* Constructor<?>[] declaredConstructors = qClass.getDeclaredConstructors(); • for (Constructor<?> declaredConstructor : declaredConstructors) { • System.*out*.println(declaredConstructor); • } • System.*out*.println("~~~~~~~~"); • *//**它只能得到本类中**public**的构造函数 \* Constructor<?>[] constructors = qClass.getConstructors(); • for (Constructor<?> constructor : constructors) { • System.*out*.println(constructor); • } • } } class BigQ{ • public BigQ(){ • System.*out*.println("父类的无参构造"); • } • public BigQ(String qq){ • System.*out*.println("父类的有参构造"+qq); • } } class Q extends BigQ{ • public Q(){ • System.*out*.println("子类的无参构造"); • } • public Q(String name){ • System.*out*.println("子类的有参构造"+name); • } • private Q(int age){ • System.*out*.println("子类的有参私有构造"+age); • } }
6.2 Constructor类中常用的方法
public class Test5 { public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class<Q> qClass = Q.class; Q q = qClass.newInstance(); System.*out*.println("---------------"); *//**得到无参构造 \* Constructor<Q> declaredConstructor = qClass.getDeclaredConstructor(); Q q1 = declaredConstructor.newInstance(); System.*out*.println("============="); *//**得到有参构造 \* Constructor<Q> declaredConstructor1 = qClass.getDeclaredConstructor(String.class); Q q2 = declaredConstructor1.newInstance("hello,world"); • } } class BigQ{ • public BigQ(){ • System.*out*.println("父类的无参构造"); • } • public BigQ(String qq){ • System.*out*.println("父类的有参构造"+qq); • } } class Q extends BigQ{ • public Q(){ • System.*out*.println("子类的无参构造"); • } • public Q(String name){ • System.*out*.println("子类的有参构造"+name); • } • private Q(int age){ • System.*out*.println("子类的有参私有构造"+age); • } }
完