目录
目标
概述
实战
获取类
获取构造方法并用反射的方式创建对象
获取成员变量
获取成员方法并通过反射的方式调用
获取注解
了解反射机制的概念,通过反射的方式动态地获取类的名称、成员变量、构造方法、成员变量,注解信息。
什么是反射
java类编译完成以后变成class字节码文件,java项目启动时会将class文件加载到内存中。此时,在运行的java程序中:
将类的各个组成部分封装成对象,这个过程就是反射。
package com.ctx.test;
public class Student {
private String name;
private String idCard;
private int age;
public String phone;
public boolean sex;
protected String address;
String tel;
public Student() {
}
public Student(String name, String idCard, int age) {
this.name = name;
this.idCard = idCard;
this.age = age;
}
public void fun() {
}
public String fun(String msg) {
return null;
}
}
public static void main(String[] args) throws ClassNotFoundException {
//方法一:通过Class.forName("全类名")获取。常用于加载配置文件,即把类名称放在配置文件中,然后读取配置文件加载类。
Class> studentClass = Class.forName("com.ctx.test.Student");
//方法二:通过类名.Class获取。常用于作为参数传递。
Class studentClass2 = Student.class;
//方法三:通过类的对象.getClass()获取。常用于对象获取字节码。
Student student = new Student();
Class extends Student> studentClass3 = student.getClass();
//都输出true,证明同一个Class文件在一次程序运行中,只会被加载一次。
System.out.println(studentClass==studentClass2);
System.out.println(studentClass2==studentClass3);
}
package com.ctx.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class GetConstructor {
String name;
Boolean sex;
Integer age;
@Override
public String toString() {
return "GetConstructor{" +
"name='" + name + '\'' +
", sex=" + sex +
", age=" + age +
'}';
}
public GetConstructor() {
}
private GetConstructor(String name) {
this.name=name;
}
GetConstructor(Integer age) {
this.age=age;
}
protected GetConstructor(Boolean sex) {
this.sex=sex;
}
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
new GetConstructor().createObject();
}
/**
* 获取构造方法
* @throws NoSuchMethodException
*/
public void getConstructor() throws NoSuchMethodException {
//获取所有的public的构造方法
Constructor>[] constructors = GetConstructor.class.getConstructors();
for (Constructor> constructor : constructors) {
System.out.println(constructor);
}
System.out.println("=================");
//设置参数列表,获取指定的public构造方法。我这里参数列表没写,获取的就是无参数的public构造方法。
Constructor constructor = GetConstructor.class.getConstructor();
System.out.println(constructor);
System.out.println("=================");
//获取所有构造方法
Constructor>[] declaredConstructors = GetConstructor.class.getDeclaredConstructors();
for (Constructor> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
System.out.println("=================");
//获取指定的构造方法。我这里指定了参数列表为String,获取的就是一个String的构造方法。
Constructor declaredConstructor = GetConstructor.class.getDeclaredConstructor(String.class);
System.out.println(declaredConstructor);
}
/**
* 通过反射的方式获取对象。
* @throws InvocationTargetException
* @throws InstantiationException
* @throws IllegalAccessException
*/
public void createObject() throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
Constructor declaredConstructor = GetConstructor.class.getDeclaredConstructor(String.class);
GetConstructor obj = declaredConstructor.newInstance("张三");
System.out.println(obj);
}
}
package com.ctx.test;
import java.lang.reflect.Field;
/**
* 获取成员变量
*/
public class GetMemberVar {
public static void main(String[] args) {
new GetMemberVar().setPrivateValue();
}
/**
* 获取public访问修饰符描述的成员变量。
*/
public void getPublicMemberVar(){
//获取所有public访问修饰符描述的成员变量。
Field[] fields = Student.class.getFields();
for (Field field : fields) {
System.out.println(field);
}
//获取指定的public类型的成员变量。
try {
Field sex = Student.class.getField("sex");
System.out.println(sex);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
/**
* 获取所有成员变量。
*/
public void getDeclareMemberVar(){
//获取所有成员变量。
Field[] declaredFields = Student.class.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//获取指定的成员变量。
try {
Field name = Student.class.getDeclaredField("name");
System.out.println(name);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
/**
* 给非private成员变量设定值。
*/
public void setValue(){
Student student = new Student();
try {
Field address = Student.class.getDeclaredField("address");
//给成员变量设值。
address.set(student,"xxxx");
//成员变量取值。
Object o = address.get(student);
System.out.println("address="+o);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* 给private成员变量设定值。
*/
public void setPrivateValue(){
Student student = new Student();
try {
Field name = Student.class.getDeclaredField("name");
//忽略访问修饰符的限制。
name.setAccessible(true);
//给成员变量设值。
name.set(student,"张三");
//成员变量取值。
Object o = name.get(student);
System.out.println("name="+o);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
package com.ctx.test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GetMethod {
String name;
@Override
public String toString() {
return "GetMethod{" +
"name='" + name + '\'' +
'}';
}
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
new GetMethod().getMethod();
}
/**
* 获取成员方法并调用
*/
public void getMethod() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Method[] methods = GetMethod.class.getMethods();
//获取所有public成员方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("================");
//获取指定的成员方法
Method test = GetMethod.class.getMethod("test", String.class);
System.out.println(test);
System.out.println("================");
//获取所有成员方法
Method[] declaredMethods = GetMethod.class.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("================");
Method test2 = GetMethod.class.getDeclaredMethod("test2",String.class);
Object zhangsan = test2.invoke(GetMethod.class.newInstance(), "zhangsan");
System.out.println(zhangsan);
}
public void test(String name) {
this.name = name;
}
private String test2(String name) {
return "a";
}
protected void test3() {
}
void test4() {
}
}
package com.ctx.test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String name() default "未知";
boolean sex() ;
int age();
}
package com.ctx.test;
import org.springframework.scheduling.annotation.Scheduled;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
@MyAnnotation(name="李四",sex = true, age = 35)
public class GetAnnotation {
public static void main(String[] args) throws NoSuchMethodException {
new GetAnnotation().getAnnotation();
}
/**
* 获取注解
*/
public void getAnnotation() throws NoSuchMethodException {
//判断方法上是否存在这个注解
Method method = GetAnnotation.class.getMethod("fun2");
boolean annotationPresent1 = method.isAnnotationPresent(Scheduled.class);
if(annotationPresent1){
Scheduled annotation = method.getAnnotation(Scheduled.class);
System.out.println(annotation.cron());
}
}
/**
* 判断注解是否存在并获取
*/
public void existAnnotation() throws NoSuchMethodException {
//判断类上是否存在这个注解
boolean annotationPresent = GetAnnotation.class.isAnnotationPresent(MyAnnotation.class);
if(annotationPresent){
MyAnnotation annotation = GetAnnotation.class.getAnnotation(MyAnnotation.class);
System.out.println(annotation.sex());
System.out.println(annotation.age());
System.out.println(annotation.name());
}
//判断方法上是否存在这个注解
Method method = GetAnnotation.class.getMethod("fun");
boolean annotationPresent1 = method.isAnnotationPresent(MyAnnotation.class);
if(annotationPresent1){
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println(annotation.sex());
System.out.println(annotation.age());
System.out.println(annotation.name());
}
}
@MyAnnotation(name="张三",sex = false, age = 18)
public void fun(){
}
@Scheduled(cron = "0 0/15 * * * ?")
public void fun2(){
}
}