Java反射的简单入门

深藏阁楼爱情的钟 2022-04-21 15:40 270阅读 0赞

1.Class的简单介绍

Class类的类表示正在运行的Java应用程序中的类和接口。 枚举是一种类,一个注解是一种接口, 每个数组也属于一个反映为类对象的类,该对象由具有相同元素类型和维数的所有数组共享。 原始Java类型( booleanbytecharshortintlongfloatdouble ),和关键字void也表示为类对象。

摘自jdk1.8中文版,刚开始看可能不懂,现在逐句来解释一下。

第一句话:一个类被加载以后,JVM就会在内存中给创建一个对应类的Class对象。

第二句话:类型相同的对象,维数相同的数组(不管长度)共享的是同一个内存中的Class对象。

第三句话:上面这些原始的类型,也会在内存中有一个与之对象的Class对象。

  1. package com.dingyu;
  2. import org.junit.Test;
  3. /**
  4. * Class的简单使用方法
  5. *
  6. * @author 70241
  7. *
  8. */
  9. public class ClassDemo {
  10. @Test
  11. public void classTest1() {
  12. try {
  13. Class class1 = Class.forName("com.dingyu.User");// 第一种获取Class对象的方法
  14. User user = new User();
  15. Class class2 = user.getClass();// 第二种获取Class对象的方法
  16. Class class3=User.class;//第三种获取Class对象的方法
  17. System.out.println("接下来判断到底同一类的不同对象的Class对象是不是同一个:"
  18. + (class1.hashCode() == class2.hashCode()&&class1.hashCode() == class3.hashCode()));
  19. } catch (ClassNotFoundException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. @Test
  24. public void classTest2() {
  25. String[] s1 = new String[10];
  26. String[] s2 = new String[30];
  27. String[][] s3 = new String[3][30];
  28. System.out.println(s1.getClass().hashCode()==s2.getClass().hashCode());
  29. System.out.println(s1.getClass().hashCode()==s3.getClass().hashCode());
  30. }
  31. }

1248002-20181123202746256-488057352.png

1248002-20181123202803465-194277815.png

2.Class获取类的属性,构造器,方法和注解的简单使用

  1. package com.dingyu;
  2. import java.lang.annotation.Annotation;
  3. import java.lang.reflect.Constructor;
  4. import java.lang.reflect.Field;
  5. import java.lang.reflect.Method;
  6. import org.junit.Test;
  7. /**
  8. * Class的简单用法
  9. *
  10. * @author dingyu
  11. *
  12. */
  13. public class ClassDemo02 {
  14. @Test
  15. public void usingClass() throws Exception {
  16. Class userClass = Class.forName("com.dingyu.User");
  17. // 获得类名
  18. System.out.println(userClass.getName());// 获得全类名
  19. System.out.println(userClass.getSimpleName());// 获得类名
  20. // 获得属性
  21. Field[] fields = userClass.getDeclaredFields();// 获得所有的属性
  22. for (Field field : fields) {
  23. System.out.println(field.getName());
  24. }
  25. System.out.println(userClass.getDeclaredField("id").getName());// 获得指定的属性
  26. // 获得方法
  27. Method[] methods = userClass.getDeclaredMethods();// 获得所有的方法
  28. for (Method method : methods) {
  29. System.out.println(method.getName());
  30. }
  31. Method method = userClass.getDeclaredMethod("setId", int.class);// 获得指定的方法,前面方法名,后面方法的参数
  32. System.out.println(method.getName());
  33. // 获得构造器
  34. Constructor[] constructors = userClass.getDeclaredConstructors();
  35. System.out.println(constructors.length);
  36. Constructor constructor = userClass.getDeclaredConstructor(int.class, String.class, int.class);// 获得指定的构造器,需要指定构造的参数
  37. System.out.println(constructor.getName());
  38. // 获得注解
  39. Annotation[] annotations = userClass.getAnnotations();
  40. for (Annotation annotation : annotations) {
  41. System.out.println(annotation);
  42. }
  43. // 指定注解名
  44. MyAnnotation annotation = (MyAnnotation)userClass.getDeclaredAnnotation(MyAnnotation.class);
  45. System.out.println(annotation);
  46. }
  47. }

3.Class动态的调用构造器,方法,修改属性

  1. package com.dingyu;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.Method;
  5. import org.junit.Test;
  6. /**
  7. * 使用反射动态的调用构造器,方法,修改属性
  8. * @author 70241
  9. *
  10. */
  11. public class ClassDemo03 {
  12. @Test
  13. @SuppressWarnings("all")
  14. public void usingClass() throws Exception {
  15. Class class1 = Class.forName("com.dingyu.User");
  16. //使用反射去调用构造器
  17. User user1 = (User) class1.newInstance();//调用的是无参的
  18. Constructor constructor = class1.getDeclaredConstructor(int.class,String.class,int.class);//获得有参的构造器
  19. User user2 = (User) constructor.newInstance(04,"dingyu",20);//动态生成对象
  20. //使用反射去调用方法
  21. Method methodSetId = class1.getDeclaredMethod("setId",int.class);
  22. methodSetId.invoke(user1, 02);//执行user1中的setId,后面是给的参数
  23. System.out.println(user1.getId());
  24. //使用反射去修改属性的值
  25. Field field = class1.getDeclaredField("age");
  26. field.setAccessible(true);//因为age是私有的,加上这句就表示这个属性不需要做安全检查
  27. field.set(user1, 20);
  28. System.out.println(field.get(user1));
  29. System.out.println(user1.getAge());
  30. }
  31. }

4.反射获得带泛型的参数或返回值里泛型的的类型  

  1. package com.dingyu;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.ParameterizedType;
  4. import java.lang.reflect.Type;
  5. import java.util.Map;
  6. /**
  7. * 反射获得带泛型的参数或返回值里泛型的的类型
  8. * @author dingyu
  9. *
  10. */
  11. public class ClassDemo04 {
  12. public void test01(Map<Integer, String> map, String s) {
  13. }
  14. public Map<Integer, String> test02() {
  15. return null;
  16. }
  17. public static void main(String[] args) throws Exception {
  18. //参数中带泛型的
  19. Method method = ClassDemo04.class.getDeclaredMethod("test01", Map.class, String.class);
  20. Type[] types = method.getGenericParameterTypes();// 返回一个 Type对象的数组, Type以声明顺序表示由该对象表示的可执行文件的形式参数类型
  21. // 打印这些参数的类型
  22. for (Type type : types) {
  23. System.out.println(type.getTypeName());
  24. if (type instanceof ParameterizedType) {// 如果是泛型的参数
  25. Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 获得泛型的的类型
  26. for (Type type2 : actualTypeArguments) {
  27. System.out.println(type2.getTypeName());
  28. }
  29. }
  30. }
  31. //返回值中带泛型的
  32. Method method02 = ClassDemo04.class.getDeclaredMethod("test02");
  33. Type type = method02.getGenericReturnType();// 返回的类型
  34. // 打印这些返回的类型
  35. System.out.println(type.getTypeName());
  36. if (type instanceof ParameterizedType) {// 如果是泛型的参数
  37. Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 获得泛型的的类型
  38. for (Type type2 : actualTypeArguments) {
  39. System.out.println(type2.getTypeName());
  40. }
  41. }
  42. }
  43. }

我有一个微信公众号,经常会分享一些Java技术相关的干货;如果你喜欢我的分享,可以用微信搜索“Java团长”或者“javatuanzhang”关注。

发表评论

表情:
评论列表 (有 0 条评论,270人围观)

还没有评论,来说两句吧...

相关阅读

    相关 关于Field简单理解

    今天在苏州,没事闲着写下自己的一份博客,自己在看代码的时候遇到问题就喜欢总结,希望有一天能成为像郭大神鸿洋这样的大神! 进入今天的正题 1.怎么通过反射获取类的属性

    相关 Java深入浅出

    刚开始接触反射这个概念,感觉反射这个机制很复杂很难懂,所以在这篇文章中对java的反射机制以个人的理解总结归纳。 1. 什么是反射? 什么是反射?在官方文档中是这样说的