反射

个人粗浅的对于反射的理解:通过调用Class静态方法forName()来动态地获取指定的Class实例(加载到内存中的类,又称运行时类),

然后调用各种方法进行创建对象或获取及调用指定结构(属性、方法、构造器等)。

复制代码
  1 package com.fly.reflection;
  2 
  3 import org.junit.Test;
  4 
  5 import java.io.IOException;
  6 import java.io.InputStream;
  7 import java.lang.annotation.Annotation;
  8 import java.lang.reflect.*;
  9 import java.util.Properties;
 10 
 11 public class ReflectionTest {
 12 
 13     /**
 14      * 获取Class实例的方式
 15      */
 16     @Test
 17     public void test1() throws ClassNotFoundException {
 18         //方式一:调用运行时类的属性
 19         Class personClass1 = Person.class;
 20         System.out.println(personClass1);
 21         //方式二:通用运行时类的对象,调用getClass()
 22         Person person = new Person();
 23         Class personClass2 = person.getClass();
 24         System.out.println(personClass2);
 25         //方式三:调用Class静态方法
 26         Class personClass3 = Class.forName("com.fly.reflection.Person");
 27         System.out.println(personClass3);
 28         //方式四:使用类的加载器:ClassLoader
 29         ClassLoader classLoader = ReflectionTest.class.getClassLoader();
 30         Class personClass4 = classLoader.loadClass("com.fly.reflection.Person");
 31         System.out.println(personClass4);
 32 
 33         System.out.println(personClass1 == personClass2);
 34         System.out.println(personClass1 == personClass3);
 35         System.out.println(personClass1 == personClass4);
 36     }
 37 
 38     /**
 39      * 读取配置文件
 40      */
 41     @Test
 42     public void test2() throws IOException {
 43         Properties properties = new Properties();
 44         //方式一  此时文件默认在当前module下
 45         //FileInputStream is = new FileInputStream("src\\reflection.properties");
 46         //方式二 此时文件默认在当前module的src下
 47         ClassLoader classLoader = ReflectionTest.class.getClassLoader();
 48         InputStream is = classLoader.getResourceAsStream("reflection.properties");
 49 
 50         properties.load(is);
 51         String username = properties.getProperty("username");
 52         String password = properties.getProperty("password");
 53         System.out.println("username = " + username + "password = " + password);
 54     }
 55 
 56     /**
 57      * 根据Class实例来创建对象
 58      */
 59     @Test
 60     public void test3() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
 61         //获取Person类
 62         Class clazz = Class.forName("com.fly.reflection.Person");
 63         //newInstance()里面调用了空参构造器(构造器权限需要足够访问)
 64         Object person = clazz.newInstance();
 65         System.out.println(person);
 66 
 67     }
 68 
 69     /**
 70      * 获取属性结构
 71      */
 72     @Test
 73     public void test4() {
 74         Class<Person> clazz = Person.class;
 75         //获取当前运行时类及父类中声明为public访问权限的属性
 76         Field[] fields = clazz.getFields();
 77         for (Field field : fields) {
 78             System.out.println(field);
 79         }
 80         System.out.println("*****************");
 81         //获取当前运行时类(不包含父类)的所有属性
 82         Field[] declaredFields = clazz.getDeclaredFields();
 83         for (Field declaredField : declaredFields) {
 84             System.out.println(declaredField);
 85         }
 86         System.out.println("*****************");
 87         for (Field field : declaredFields) {
 88             //权限修饰符
 89             int modifier = field.getModifiers();
 90             System.out.print(Modifier.toString(modifier) + "\t");
 91             //数据类型
 92             Class type = field.getType();
 93             System.out.print(type.getName()  + "\t");
 94             //变量名
 95             String name = field.getName();
 96             System.out.print(name);
 97 
 98             System.out.println();
 99         }
100     }
101 
102     /**
103      * 获取方法结构
104      */
105     @Test
106     public void test5() throws NoSuchMethodException {
107         Class<Person> clazz = Person.class;
108         //获取当前运行时类及所有父类中声明为public权限的方法
109         Method[] methods = clazz.getMethods();
110         for (Method method : methods) {
111             System.out.println(method);
112         }
113         System.out.println("**************");
114         //获取当前运行时类(不包含父类)的所有方法
115         Method[] declaredMethods = clazz.getDeclaredMethods();
116         for (Method method : declaredMethods) {
117             System.out.println(method);
118         }
119         System.out.println("*****************");
120         Method showScore = clazz.getDeclaredMethod("showScore", double.class);
121         //获取方法声明的注解
122         Annotation[] annotations = showScore.getAnnotations();
123         for (Annotation annotation : annotations) {
124             System.out.println(annotation);
125         }
126         //获取权限修饰符
127         int modifiers = showScore.getModifiers();
128         System.out.println(Modifier.toString(modifiers));
129         //获取返回值类型
130         Class returnType = showScore.getReturnType();
131         System.out.println(returnType.getName());
132         //获取方法名
133         String name = showScore.getName();
134         System.out.println(name);
135         //获取形参列表
136         Class[] parameterTypes = showScore.getParameterTypes();
137         System.out.println(parameterTypes[0].getName());
138         //获取抛出的异常
139         Class[] exceptionTypes = showScore.getExceptionTypes();
140         System.out.println(exceptionTypes[0].getName());
141 
142     }
143 
144     /**
145      * 获取构造器结构
146      * 构造器与方法类似,可获取构造器的权限修饰符等
147      */
148     @Test
149     public void test6() {
150         Class clazz = Person.class;
151         //获取当前运行时类(不包含父类)中声明为public权限的构造器
152         Constructor[] constructors = clazz.getConstructors();
153         for (Constructor constructor : constructors) {
154             System.out.println(constructor);
155         }
156         System.out.println("*************");
157         //获取当前运行时类(不包含父类)的所有构造器
158         Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
159         for (Constructor constructor : declaredConstructors) {
160             System.out.println(constructor);
161         }
162     }
163 
164     /**
165      * 获取运行时类的父类或父类的泛型
166      */
167     @Test
168     public void test7() {
169         Class clazz = Person.class;
170         //获取运行时类的父类
171         Class superclass = clazz.getSuperclass();
172         System.out.println(superclass);
173         System.out.println("**********");
174         //获取运行时类的带泛型的父类  //Class<T> implements Type
175         Type genericSuperclass = clazz.getGenericSuperclass();
176         System.out.println(genericSuperclass);
177         //获取运行时类的带泛型的父类的泛型
178         ParameterizedType paramType = (ParameterizedType) genericSuperclass;
179         Type[] arguments = paramType.getActualTypeArguments();
180         System.out.println(arguments[0].getTypeName() + "或者" + ((Class)arguments[0]).getName());
181 
182     }
183 
184     /**
185      * 获取运行时类及父类实现的接口
186      */
187     @Test
188     public void test8() {
189         Class clazz = Person.class;
190         //获取运行时类实现的接口
191         Class[] interfaces = clazz.getInterfaces();
192         for (Class anInterface : interfaces) {
193             System.out.println(anInterface);
194         }
195         System.out.println("**********");
196         //获取运行时类的父类实现的接口
197         Class superclass = clazz.getSuperclass();
198         Class[] superInterfaces = superclass.getInterfaces();
199         System.out.println(superInterfaces[0]);
200     }
201 
202     /**
203      * 获取运行时类所在的包
204      */
205     @Test
206     public void test9() {
207         Class clazz = Person.class;
208         //获取运行时类所在的包
209         Package aPackage = clazz.getPackage();
210         System.out.println(aPackage);
211     }
212 
213     /**
214      * 获取运行时类声明的注解
215      */
216     @Test
217     public void test10() {
218         Class clazz = Person.class;
219         //获取运行时类声明的注解
220         Annotation[] annotations = clazz.getAnnotations();
221         System.out.println(annotations[0]);
222     }
223 
224     /**
225      * 调用运行时类中指定的属性
226      */
227     @Test
228     public void test11() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
229         Class<Person> clazz = Person.class;
230         //创建运行时类的对象
231         Person person = clazz.newInstance();
232         //获取指定的属性,要求属性是public的
233         Field score = clazz.getField("score");
234         /**
235          * 设置当前属性的值
236          * 参数一:指明是设置哪个对象的属性
237          * 参数二:属性值
238          */
239         score.set(person,12.23);
240         /**
241          * 获取当前属性的值
242          * 参数一:获取哪个对象的属性值
243          */
244         Object o = score.get(person);
245         System.out.println((double)o);
246 
247     }
248 
249     /**
250      * 调用运行时类中指定的属性
251      */
252     @Test
253     public void test12() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
254         Class<Person> clazz = Person.class;
255         //创建运行时类的对象
256         Person person = clazz.newInstance();
257         //获取指定的属性
258         Field name = clazz.getDeclaredField("name");
259         //将不是public修饰的属性设置为可访问的
260         name.setAccessible(true);
261         //设置指定对象当前属性的值
262         name.set(person,"Tom");
263         //获取指定对象当前属性的值
264         String o = (String) name.get(person);
265         System.out.println(o);
266 
267     }
268 
269     /**
270      * 调用运行时类中指定的方法
271      */
272     @Test
273     public void test13() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
274         Class<Person> clazz = Person.class;
275         //创建运行时类的对象
276         Person person = clazz.newInstance();
277         /**
278          * 获取指定的方法
279          * 参数一:方法名
280          * 参数二:形参列表的类型
281          */
282         Method showScore = clazz.getDeclaredMethod("showScore", double.class);
283         //将不是public修饰的方法设置为可访问的
284         showScore.setAccessible(true);
285         /**
286          * 执行方法:返回值即为方法执行后的返回值
287          * 参数一:方法的调用者
288          * 参数二:给方法形参赋值的实参
289          */
290         Object invoke = showScore.invoke(person, 23.45);
291         System.out.println((double)invoke);
292 
293         /******************调用静态方法******************/
294         Method display = clazz.getDeclaredMethod("display");
295         display.setAccessible(true);
296         //如果被调用的方法没有返回值,则invoke()返回null
297         display.invoke(clazz);
298         display.invoke(null);
299 
300     }
301 
302     /**
303      * 调用运行时类中指定的构造器
304      */
305     @Test
306     public void test14() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
307         Class<Person> clazz = Person.class;
308         /**
309          * 获取指定的构造器
310          * 参数:形参列表的类型
311          */
312         Constructor<Person> declaredConstructor = clazz.getDeclaredConstructor(String.class);
313         //将不是public修饰的构造器设置为可访问的
314         declaredConstructor.setAccessible(true);
315         //创建对象
316         Person person = declaredConstructor.newInstance("Tom");
317         System.out.println(person);
318     }
319 }
复制代码

下面是上面代码使用过的类、接口、注解

复制代码
public class Creature<T> implements Serializable {

    private char gender;
    public double weight;
    T describe;

    private void breath() {
        System.out.println("生物呼吸");
    }

    public void eat() {
        System.out.println("生物吃东西");
    }
}

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "hello";
}

public interface MyInterface {
    void impleMethod();
}

@MyAnnotation(value = "hi")
public class Person extends Creature<String> implements Comparable<Person>, MyInterface {

    private String name;
    int age;
    public double score;

    public Person() {
    }

    @MyAnnotation(value = "abc")
    private Person(String name) {
        this.name = name;
    }

    Person(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public void showInfo() {
        System.out.println("showInfo()....");
    }

    private static void display() {
        System.out.println("display.......");
    }

    @MyAnnotation
    private double showScore(double score) throws RuntimeException {
        System.out.println("showScore:" + score);
        return score;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    @Override
    public int compareTo(Person o) {
        return 0;
    }

    @Override
    public void impleMethod() {
        System.out.println("我是人");
    }
}
复制代码

 

posted @   Java厨师长  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示