通过反射来:获取当前运行时类的属性结构,运行时类的方法结构
调用运行时类中指定的结构:属性,方法,构造器
首先我们创建一个实体类Person来演示,同时我们要给Person类疯狂加buff
自定义注解:
package com.atguigu.java1;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
/**
* @author ***
* @create 2022-05-14 9:20
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "hello";
}
Person父类:Creature<T> :
package com.atguigu.java1;
import java.io.Serializable;
/**
* @author ***
* @create 2022-05-14 9:10
*/
public class Creature<T> implements Serializable {
private char gender;
public double weight;
private void breath(){
System.out.println("生物呼吸");
}
public void eat(){
System.out.println("生物吃东西");
}
}
MyInterface接口:
package com.atguigu.java1;
/**
* @author ***
* @create 2022-05-14 9:14
*/
public interface MyInterface {
void info();
}
Person类:
package com.atguigu.java1;
/**
* @author ***
* @create 2022-05-14 9:09
*/
@MyAnnotation(value = "hi")
public class Person extends Creature<String> implements Comparable<String>,MyInterface{
private String name;
int age;
public int id;
public Person() {
}
@MyAnnotation(value = "abc")
private Person(String name) {
this.name = name;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
@MyAnnotation
private String show(String nation){
System.out.println("我的国籍是:" + nation);
return nation;
}
public String display(String interests){
return interests;
}
@Override
public int compareTo(String o) {
return 0;
}
@Override
public void info() {
System.out.println("我是一个人");
}
private static void showDesc(){
System.out.println("我是一个可爱的人");
}
}
获取当前运行时类的属性结构:
package com.atguigu.java2;
import com.atguigu.java1.Person;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* 获取当前运行时类的属性结构
*
* @author ***
* @create 2022-05-14 9:26
*/
public class FieldTest {
@Test
public void test1(){
Class clazz = Person.class;
//获取属性结构
//getFields():获取当前运行时类及其父类所有public的属性
Field[] fields = clazz.getFields();
for(Field f : fields){
System.out.println(f);
}
System.out.println("```````````````");
//getDeclaredFields():获取当前运行时类中所有的属性,不考虑权限(不考虑父类中的属性)
Field[] declaredFields = clazz.getDeclaredFields();
for (Field f : declaredFields){
System.out.println(f);
}
}
//权限修饰符 数据类型 变量名
@Test
public void test2(){
Class clazz = Person.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field f : declaredFields){
//1.权限修饰符
int modifier = f.getModifiers();
System.out.print(Modifier.toString(modifier) + "\t");
//2.数据类型
Class type = f.getType();
System.out.print(type.getName() + "\t");
//3.变量名
String fName = f.getName();
System.out.print(fName);
System.out.println();
}
}
}
运行时类的方法结构:
package com.atguigu.java2;
import com.atguigu.java1.Person;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 运行时类的方法结构
*
* @author ***
* @create 2022-05-14 9:44
*/
public class MethodTest {
@Test
public void test1(){
Class clazz = Person.class;
//getMethods():获取当前运行时类及其父类所有public的方法
Method[] methods = clazz.getMethods();
for(Method m : methods){
System.out.println(m);
}
System.out.println("``````````````");
//getDeclaredMethods()获取当前运行时类中所有的方法,不考虑权限(不考虑父类中的方法)
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method m : declaredMethods){
System.out.println(m);
}
}
/*
@Xxxx
权限修饰符 返回值 方法名(参数1,参数2....)throws XxxException
*/
@Test
public void test2(){
Class clazz = Person.class;
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method m : declaredMethods){
//1.获取方法声名的注解
Annotation[] annos = m.getAnnotations();
for(Annotation a : annos){
System.out.println(a);
}
//2.权限修饰符
System.out.print(Modifier.toString(m.getModifiers()) + "\t");
//3.返回值类型
System.out.print(m.getReturnType().getName() + "\t");
//4.方法名
System.out.print(m.getName());
//5.形参列表
System.out.print("(");
Class[] parameterTypes = m.getParameterTypes();
if(!(parameterTypes == null && parameterTypes.length == 0)){
for (int i = 0;i < parameterTypes.length;i++){
System.out.print(parameterTypes[i].getName() + "args_" + i);
}
}
System.out.print(")");
//6.抛出异常
Class[] exceptionTypes = m.getExceptionTypes();
if(!(exceptionTypes == null && exceptionTypes.length == 0)){
System.out.println("throws");
for(int i = 0 ; i < exceptionTypes.length ; i++){
System.out.println(exceptionTypes[i].getName());
}
}
System.out.println();
}
}
}
其他(获取构造器,获取运行时类的父类,获取运行时类的带泛型父类,获取运行时类的带泛型父类的泛型,获取运行时类实现的接口,获取运行时类所在的包,获取运行时类声名的注解,):
package com.atguigu.java2;
import com.atguigu.java1.Person;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* @author ***
* @create 2022-05-14 10:11
*/
public class OtherTest {
/*
获取构造器
*/
@Test
public void test1(){
Class clazz = Person.class;
//getConstructors():获取当前运行时类中public的构造器
Constructor[] constructors = clazz.getConstructors();
for(Constructor c : constructors){
System.out.println(c);
}
System.out.println();
//getDeclaredConstructors():获取当前运行时类中所有的构造器
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for(Constructor c : declaredConstructors){
System.out.println(c);
}
}
/*
获取运行时类的父类
*/
@Test
public void test2(){
Class clazz = Person.class;
Class superclass = clazz.getSuperclass();
System.out.println(superclass);
}
/*
获取运行时类的带泛型父类
*/
@Test
public void test3(){
Class clazz = Person.class;
Type genericSuperclass = clazz.getGenericSuperclass();
System.out.println(genericSuperclass);
}
/*
获取运行时类的带泛型父类的泛型
*/
@Test
public void test4(){
Class clazz = Person.class;
Type genericSuperclass = clazz.getGenericSuperclass();
ParameterizedType paramType = (ParameterizedType) genericSuperclass;
//获取泛型类型
Type[] actualTypeArguments = paramType.getActualTypeArguments();
System.out.println(actualTypeArguments[0].getTypeName());
}
/*
获取运行时类实现的接口
*/
@Test
public void test5(){
Class clazz = Person.class;
Class[] interfaces = clazz.getInterfaces();
for(Class i : interfaces){
System.out.println(i);
}
}
/*
获取运行时类所在的包
*/
@Test
public void test6(){
Class clazz = Person.class;
Package aPackage = clazz.getPackage();
System.out.println(aPackage);
}
/*
获取运行时类声名的注解
*/
@Test
public void test7(){
Class clazz = Person.class;
Annotation[] annotations = clazz.getAnnotations();
for (Annotation a : annotations){
System.out.println(a);
}
}
}
操作运行时类指定的属性和方法,调用运行时类中的指定的构造器:
package com.atguigu.java2;
import com.atguigu.java1.Person;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 调用运行时类中指定的结构:属性,方法,构造器
*
* @author ***
* @create 2022-05-14 10:34
*/
public class ReflectionTest {
/*
*/
@Test
public void test1() throws Exception {
Class clazz = Person.class;
//创建运行时类的对象
Person person = (Person) clazz.newInstance();
//获取指定的属性:要求运行时类属性声名为public
Field id = clazz.getField("id");
//设置当前属性的值
id.set(person,1001);
//获取当前属性的值
int pId = (int)id.get(person);
System.out.println(pId);
}
/*
如何操作运行时类指定的属性
*/
@Test
public void test2() throws Exception {
Class clazz = Person.class;
//创建运行时类的对象
Person person = (Person) clazz.newInstance();
//获取指定的属性
Field name = clazz.getDeclaredField("name");
//保证当前属性是可访问的
name.setAccessible(true);
name.set(person,"Tom");
System.out.println(name.get(person));
}
/*
如何操作运行时类指定的方法
*/
@Test
public void test3() throws Exception {
Class clazz = Person.class;
//创建运行时类的对象
Person p = (Person)clazz.newInstance();
/*
获取指定的方法
getDeclaredMethod():
参数1:指明获取的方法名
参数2:指明获取的方法的参数列表
*/
Method show = clazz.getDeclaredMethod("show", String.class);
//保证当前方法是可访问的
show.setAccessible(true);
/*
invoke():
参数1:方法的调用者
参数2:给方法形参赋值的实参
invoke()方法的返回值即为对应类中调用的方法的返回值
*/
Object chn = show.invoke(p, "CHN");
System.out.println(chn);
System.out.println("***********************如何调用静态方法*************");
Method showDesc = clazz.getDeclaredMethod("showDesc");
showDesc.setAccessible(true);
showDesc.invoke(Person.class);
}
/*
如何调用运行时类中的指定的构造器
*/
@Test
public void test4() throws Exception {
Class clazz = Person.class;
//1.获取指定构造器
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
//2.保证可访问
declaredConstructor.setAccessible(true);
//3.调用此构造器创建运行时类对象
Person person = (Person)declaredConstructor.newInstance("Tom");
}
}