什么是java反射
1.反射是框架的灵魂
2.在代码运行时在我们的磁盘中源码会被javac转换为字节码然后通过ClassLoader类加载器会在JVM内存中反射为相应的类对象。
获取反射类对象
获取类对象的方式有三种(我这里使用的是Student类)
Student类
package demo;
public class Student {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
反射类
package demo;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//第一种:根据Student类路径获取Student的反射类对象
Class<?> aClass = Class.forName("demo.Student");
//第二种:根据类名获取Student类的反射对象
Class<Student> fan1Class = Student.class;
//第三种:通过类对象获取类的反射类对象
Student f = new Student();
Class<? extends Student> aClass1 = f.getClass();
System.out.println(aClass1);
}
}
通过反射类获取类对象
这里的类还是使用的上方的Student类
反射类
package demo;
public class Test1 {
public static void main(String[] args) throws Exception {
//根据Student类的路径获取反射类对象
Class<Student> aClass = (Class<Student>) Class.forName("demo.Student");
/**
* 通过反射类得到相应的类对象---通过Student类对象调用newInstance
* 通常都是用别人封装好的方法:new Student来获取Student对象
*
*/
Student student = aClass.newInstance();
}
}
获取反射中的属性成员对象
源码转换为字节码后会以File类对象的形式存在。
Student类
package demo;
public class Student extends People {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Student父类People类
package demo;
public class People {
public String address;
private String watches;
}
测试类
通过属性名获取的时候如果属性为private时会报错误
Exception in thread “main” java.lang.NoSuchFieldException: watches
at java.lang.Class.getField(Class.java:1703)
at demo.Test2.main(Test2.java:27)
解决方法请看下文
package demo;
import java.lang.reflect.Field;
public class Test2 {
public static void main(String[] args) throws Exception {
//获取Student类的反射类
Class<Student> studentClass = Student.class;
/**
* 获取反射类中的成员对象
* getDeclaredFields获取本类中所有的属性对象
*/
Field[] declaredFields = studentClass.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field);
}
/**
* getFields获取本类以及父类中的public属性对象
*/
Field[] fields = studentClass.getFields();
for (Field f : fields) {
System.out.println(f);
}
/**
* getField通过属性的名字获取
*/
Field address = studentClass.getField("address");
System.out.println(address);
}
}
Field类中的常用方法
Doctor类
package demo;
public class Doctor {
@MyAnn(value = "年龄")
private Integer age;
public String name;
@Override
public String toString() {
return "Doctor{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
注解MyAnn类
package demo;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @Retention不写的话会报错误 Exception in thread "main" java.lang.NullPointerException
* at demo.Test3.main(Test3.java:32)
* 因为没有@Retention无法在反射时显现
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnn {
String value();
}
测试类
package demo;
import java.lang.reflect.Field;
public class Test3 {
public static void main(String[] args) throws Exception {
//通过路径获取反射类对象
Class<?> aClass = Class.forName("demo.Doctor");
//通过反射类得到类对象
Object o = aClass.newInstance();
/**
* 这时打印的为值为空
* Doctor{age=null, name='null'}
*/
System.out.println(o);
//获取反射类中的name属性对象
Field nameField = aClass.getDeclaredField("name");
//通过name属性对象为Doctor对象赋值
nameField.set(o, "小张");
//打印结果为 Doctor{age=null, name='小张'}
System.out.println(o);
Field ageField = aClass.getDeclaredField("age");
//age属性为私有的无法访问 需要设置允许否则回报上面遇到的错误
ageField.setAccessible(true);
ageField.set(o, 23);
//打印Doctor{age=23, name='小张'}
System.out.println(o);
/*获取属性上的注解对象
*打印--年龄
*/
MyAnn annotation = ageField.getAnnotation(MyAnn.class);
System.out.println(annotation.value());
}
}
获取方法类对象
Method
teacher类
package demo2;
public class Teacher extends People{
public String fun1() {
System.out.println("--1");
return "teacherMan";
}
public String fun1(int age) {
System.out.println("==1");
return "teacherMan";
}
public String fun2(int age) {
System.out.println("==2");
return "teacher" + age;
}
private void fun3() {
System.out.println("++3");
}
}
teacher父类people
package demo2;
public class People {
public String fun() {
System.out.println("p--");
return "teacher";
}
private void fun2() {
System.out.println("p==");
}
}
测试类
package demo2;
import java.lang.reflect.Method;
public class Test3 {
public static void main(String[] args) throws Exception {
Class<Teacher> teacherClass = Teacher.class;
teacherClass.newInstance();
/**
* 获取类中所有的Method方法对象
* 输出
* public java.lang.String demo2.Teacher.fun1(int)
* public java.lang.String demo2.Teacher.fun1()
* private void demo2.Teacher.fun3()
* public java.lang.String demo2.Teacher.fun2(int)
*/
// Method[] declaredMethods = teacherClass.getDeclaredMethods();
// for (Method m:declaredMethods) {
// System.out.println(m);
// }
/**
* 获取本类以及父辈的中public修饰的方法对象--可以从输出值来判断
* 输出
* public java.lang.String demo2.Teacher.fun2(int)
* public java.lang.String demo2.Teacher.fun1(int)
* public java.lang.String demo2.Teacher.fun1()
* public java.lang.String demo2.People.fun()
* public final void java.lang.Object.wait() throws java.lang.InterruptedException
* public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
* public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
* public boolean java.lang.Object.equals(java.lang.Object)
* public java.lang.String java.lang.Object.toString()
* public native int java.lang.Object.hashCode()
* public final native java.lang.Class java.lang.Object.getClass()
* public final native void java.lang.Object.notify()
* public final native void java.lang.Object.notifyAll()
*/
// Method[] methods = teacherClass.getMethods();
// for (Method m:methods) {
// System.out.println(m);
// }
/**
* getMethod通过名字获取
* 书写int.class参数输出结果为
* public java.lang.String demo2.Teacher.fun1(int)
* 没有书写参数时输出为
* public java.lang.String demo2.Teacher.fun1()
*/
Method fun1 = teacherClass.getMethod("fun1", int.class);
System.out.println(fun1);
}
}
Method类中常用方法
teacher类
package demo2;
public class Teacher extends People {
public String fun1() {
System.out.println("--1");
return "teacherMan";
}
@My("你好")
public String fun1(int age) {
System.out.println("==1" + age);
return "teacherMan";
}
public String fun2(int age) {
System.out.println("==2");
return age + "teacher";
}
private void fun3() {
System.out.println("++3");
}
}
注解
package demo2;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface My {
String value();
}
测试
package demo2;
import java.lang.reflect.Method;
public class Test4 {
public static void main(String[] args) throws Exception {
Class<Teacher> teacherClass = Teacher.class;
Teacher teacher = teacherClass.newInstance();
Method fun = teacherClass.getMethod("fun1", int.class);
//回调fun1方法 执行fun1方法
Object invoke = fun.invoke(teacher, 23);
System.out.println(invoke);
//注解
My annotation = fun.getAnnotation(My.class);
System.out.println(annotation.value());
}
}
获取构造对象
子类
package demo2;
public class Z extends F {
public Z() {
super();//默认拥有
System.out.println("子类的无参");
}
public Z(String name) {
System.out.println("子类的有参:" + name);
}
private Z(Integer age) {
System.out.println("有参私有构造");
}
}
父类
package demo2;
public class F {
public F() {
System.out.println("父类的无参");
}
public F(String name) {
System.out.println("父类的有参:" + name);
}
}
测试
package demo2;
import java.lang.reflect.Constructor;
public class Test5 {
public static void main(String[] args) throws Exception {
Class<Z> zClass = Z.class;
Object o = zClass.newInstance(); //得到类对象---调用构造函数
Constructor<?>[] declaredConstructors = zClass.getDeclaredConstructors();
for (Constructor c : declaredConstructors) {
System.out.println(c);
}
//它只能得到本类中public的构造函数
Constructor<?>[] declaredConstructors2 = zClass.getConstructors();
for (Constructor c : declaredConstructors2) {
System.out.println(c);
}
}
}
constructor常用方法
其他类引用上面的
测试类
package demo2;
import java.lang.reflect.Constructor;
public class Test5 {
public static void main(String[] args) throws Exception {
Class<Z> zClass = Z.class;
Object o = zClass.newInstance();
Constructor<Z> declaredConstructor = zClass.getDeclaredConstructor(String.class);
Z hello = declaredConstructor.newInstance("hello");
System.out.println(hello);
}
}