注解与反射机制

阳光穿透心脏的1/2处 2024-04-20 11:20 133阅读 0赞

注解与反射机制

一、注解

1.什么是注解

java.annotation包
Annotation是从JDK1.5开始引入的新技术,注解即可以对程序员解释又可以对程序解释

2.注解与注释的区别

注释:对程序员解释代码信息

注解:对程序和程序员解释代码信息

3.注解的所用

不是程序本身,可以对程序作出解释(与注释(comment)类似)

可以被其他程序(编译器)读取

4.注解的格式

注解是以“@注释名”在代码中存在的,还可以添加一些参数

例如:@SuppressWarnings(value=“unchecked”)

5.注解的应用

可以附加在package、class、method、field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制实现对这些数据的访问

6.内置注解

@Overrlde:定义在java.lang.Override中,此注解只适用于修饰方法,表示一个方法声明打算重写超类中的另一个方法声明

@Deprecated:定义在java.lang.Deprecated中.此注解可以用于修饰方法,属性,类。表示不鼓励使用这样的元素.通常是因为它很危险或者存在更好的选择

@SuppressWarnings:镇压警告,定义在java.lang.SuppressWarnings中用来抑制编译时的警告信息,与前两个注释有所不同.你需要添加参数才能正确使用。这些参数都是已经定义好了的.我们选择性的使用就好了
@SuppressWarnings(“all”)抑制所有类型的警告信息
@SuppressWarnings(“unchecked”)抑制单类型的警告信息
@SuppressWarnings(value={“unchecked”,“deprecation”})抑制多类型的警告信息

7.元注解

元注解的作用:负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明

这些类型和它们所支持的类在java.lang.annotation包中可以找到

(@Target,@Retention,@Documented,@Inherited )

@Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

@Retention:表示需要要在什么级别保存该注择信息,用于描述注解的生命周期

(SOURCE < CLASS <RUNTIME)

@Document:说明该注解将被包含在javadoc中

@lnherited:说明子类可以继承父类中的该注解

  1. @MyAnnotation02
  2. public class Test01<@MyAnnotation02 T> {
  3. @MyAnnotation02
  4. public String name;
  5. @MyAnnotation02
  6. public Test01() {
  7. }
  8. @MyAnnotation01
  9. @MyAnnotation02
  10. @MyAnnotation03("aaa")
  11. @MyAnnotation04
  12. @MyAnnotation05(name = "aaa")
  13. @MyAnnotation06(names = {
  14. "aaa","bbb"})
  15. @MyAnnotation07(names={
  16. "aaa","bbb"},username="撕裂的忧伤")
  17. public void method(String str){
  18. @MyAnnotation02
  19. int i = 100;
  20. System.out.println(i);
  21. }
  22. }
  23. import java.lang.annotation.ElementType;
  24. import java.lang.annotation.Retention;
  25. import java.lang.annotation.RetentionPolicy;
  26. import java.lang.annotation.Target;
  27. /**
  28. * 该注解只能在方法上使用,并且没有参数
  29. */
  30. @Target(ElementType.METHOD)
  31. @Retention(RetentionPolicy.RUNTIME)
  32. public @interface MyAnnotation01 {
  33. }
  34. import static java.lang.annotation.ElementType.*;
  35. import java.lang.annotation.Retention;
  36. import java.lang.annotation.RetentionPolicy;
  37. import java.lang.annotation.Target;
  38. /**
  39. * 该注解可以在方法、类、构造方法、属性、局部变量、泛型上使用,并且没有参数
  40. */
  41. @Target({
  42. METHOD,TYPE,CONSTRUCTOR,FIELD,LOCAL_VARIABLE,TYPE_PARAMETER})
  43. @Retention(RetentionPolicy.RUNTIME)
  44. public @interface MyAnnotation02 {
  45. }
  46. import static java.lang.annotation.ElementType.*;
  47. import java.lang.annotation.Retention;
  48. import java.lang.annotation.RetentionPolicy;
  49. import java.lang.annotation.Target;
  50. /**
  51. * 该注解可以在方法上使用,并且有一个参数
  52. */
  53. @Target(METHOD)
  54. @Retention(RetentionPolicy.RUNTIME)
  55. public @interface MyAnnotation03 {
  56. String value();
  57. }
  58. import static java.lang.annotation.ElementType.*;
  59. import java.lang.annotation.Retention;
  60. import java.lang.annotation.RetentionPolicy;
  61. import java.lang.annotation.Target;
  62. /**
  63. * 该注解可以在方法上使用,并且有一个参数
  64. */
  65. @Target(METHOD)
  66. @Retention(RetentionPolicy.RUNTIME)
  67. public @interface MyAnnotation04 {
  68. String value() default "abc";//设置默认值
  69. }
  70. import static java.lang.annotation.ElementType.*;
  71. import java.lang.annotation.Retention;
  72. import java.lang.annotation.RetentionPolicy;
  73. import java.lang.annotation.Target;
  74. /**
  75. * 该注解可以在方法上使用,并且有一个参数
  76. */
  77. @Target(METHOD)
  78. @Retention(RetentionPolicy.RUNTIME)
  79. public @interface MyAnnotation05 {
  80. String name();
  81. }
  82. import static java.lang.annotation.ElementType.*;
  83. import java.lang.annotation.Retention;
  84. import java.lang.annotation.RetentionPolicy;
  85. import java.lang.annotation.Target;
  86. /**
  87. * 该注解可以在方法上使用,并且有一个参数
  88. */
  89. @Target(METHOD)
  90. @Retention(RetentionPolicy.RUNTIME)
  91. public @interface MyAnnotation06 {
  92. String[] names();
  93. }
  94. import static java.lang.annotation.ElementType.*;
  95. import java.lang.annotation.Retention;
  96. import java.lang.annotation.RetentionPolicy;
  97. import java.lang.annotation.Target;
  98. /**
  99. * 该注解可以在方法上使用,并且有一个参数
  100. */
  101. @Target(METHOD)
  102. @Retention(RetentionPolicy.RUNTIME)
  103. public @interface MyAnnotation07 {
  104. String[] names();
  105. String username();
  106. String password() default "00000000";
  107. }

8.自定义注解

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口

分析:

@interface用来声明一个注解,格式:public @interface注解名{定义内容}

其中的每一个方法实际上是声明了一个配置参数.

方法的名称就是参数的名称.

返回值类型就是参数的类型(返回值只能是基本类型、Class、String、enum)

可以通过default来声明参数的默认值

如果只有一个参数成员,一般参数名为value()

注解元素必須要有值,我们定义注解元素时,经常使用空字符串.0作为默认值

  1. import java.util.ArrayList;
  2. public class test01 {
  3. //重写的注解
  4. @Override
  5. public boolean equals(Object obj) {
  6. return super.equals(obj);
  7. }
  8. //过时的注解
  9. @Deprecated
  10. public void method01(){
  11. }
  12. //镇压警告的注解
  13. @SuppressWarnings("all")
  14. public void method02(){
  15. ArrayList list = new ArrayList();
  16. list.add(134);
  17. list.add("abc");
  18. }
  19. }

二、反射机制

1.含义:

使用到一个类,该类的class文件会加载到方法区,并且在堆中创建该类的class对象,class对象作为class文件的访问入口,反射就是获取class对象,拿到class对象就可以访问class文件(换言之,可以对该类为所欲为-属性、构造方法、方法)

  1. public class Student extends Person{
  2. private String classId;
  3. private String id;
  4. public Student() {
  5. }
  6. // private Student(String classId, String id) {
  7. // this.classId = classId;
  8. // this.id = id;
  9. // }
  10. public Student(String name, char sex, int age, String classId, String id) {
  11. super(name, sex, age);
  12. this.classId = classId;
  13. this.id = id;
  14. }
  15. public String getClassId() {
  16. return classId;
  17. }
  18. public void setClassId(String classId) {
  19. this.classId = classId;
  20. }
  21. public String getId() {
  22. return id;
  23. }
  24. public void setId(String id) {
  25. this.id = id;
  26. }
  27. @Override
  28. public String toString() {
  29. return "Student [classId=" + classId + ", id=" + id + ", getName()=" + getName() + ", getSex()=" + getSex()
  30. + ", getAge()=" + getAge() + "]";
  31. }
  32. // private String method01(String str){
  33. // System.out.println("私有的方法 :" + str);
  34. // return "用良心做教育";
  35. // }
  36. public static void method02(){
  37. System.out.println("静态的方法");
  38. }
  39. }
  40. public class Person {
  41. private String name;
  42. private char sex;
  43. private int age;
  44. public Person() {
  45. }
  46. public Person(String name, char sex, int age) {
  47. this.name = name;
  48. this.sex = sex;
  49. this.age = age;
  50. }
  51. public String getName() {
  52. return name;
  53. }
  54. public void setName(String name) {
  55. this.name = name;
  56. }
  57. public char getSex() {
  58. return sex;
  59. }
  60. public void setSex(char sex) {
  61. this.sex = sex;
  62. }
  63. public int getAge() {
  64. return age;
  65. }
  66. public void setAge(int age) {
  67. this.age = age;
  68. }
  69. @Override
  70. public String toString() {
  71. return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
  72. }
  73. }
  74. import java.lang.reflect.Constructor;
  75. import java.lang.reflect.Field;
  76. import java.lang.reflect.InvocationTargetException;
  77. import java.lang.reflect.Method;
  78. import java.util.ArrayList;
  79. import java.util.Collections;
  80. import java.util.List;
  81. //反射工具类
  82. public class ReflexUtil {
  83. //获取该类及其父类所有的属性对象
  84. public static List<Field> getAllField(Class<?> clazz){
  85. List<Field> list = new ArrayList<>();
  86. for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
  87. Field[] fields = c.getDeclaredFields();
  88. Collections.addAll(list, fields);
  89. }
  90. return list;
  91. }
  92. //获取该类及其父类指定的属性对象
  93. public static Field getField(Class<?> clazz,String fieldName){
  94. for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
  95. try {
  96. Field field = c.getDeclaredField(fieldName);
  97. return field;
  98. } catch (NoSuchFieldException e) {
  99. //如果该类中找不到属性就会出现该异常
  100. }
  101. }
  102. return null;
  103. }
  104. //设置对象中的属性
  105. public static void setField(Object obj,String fieldName,Object value){
  106. Field field = getField(obj.getClass(), fieldName);
  107. field.setAccessible(true);
  108. try {
  109. field.set(obj, value);
  110. } catch (IllegalArgumentException e) {
  111. e.printStackTrace();
  112. } catch (IllegalAccessException e) {
  113. e.printStackTrace();
  114. }
  115. }
  116. //获取该类及其父类所有的构造对象
  117. public static List<Constructor<?>> getAllConstructor(Class<?> clazz){
  118. List<Constructor<?>> list = new ArrayList<>();
  119. for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
  120. Constructor<?>[] constructors = c.getDeclaredConstructors();
  121. Collections.addAll(list, constructors);
  122. }
  123. return list;
  124. }
  125. //创建该类的对象
  126. public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] values){
  127. try {
  128. Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
  129. constructor.setAccessible(true);
  130. T t = constructor.newInstance(values);
  131. return t;
  132. } catch (NoSuchMethodException e) {
  133. e.printStackTrace();
  134. } catch (SecurityException e) {
  135. e.printStackTrace();
  136. } catch (InstantiationException e) {
  137. e.printStackTrace();
  138. } catch (IllegalAccessException e) {
  139. e.printStackTrace();
  140. } catch (IllegalArgumentException e) {
  141. e.printStackTrace();
  142. } catch (InvocationTargetException e) {
  143. e.printStackTrace();
  144. }
  145. return null;
  146. }
  147. //获取该类及其父类所有的方法对象
  148. public static List<Method> getAllMethod(Class<?> clazz){
  149. List<Method> list = new ArrayList<>();
  150. for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
  151. Method[] methods = c.getDeclaredMethods();
  152. Collections.addAll(list, methods);
  153. }
  154. return list;
  155. }
  156. //获取指定的方法对象
  157. public static Method getMethod(Class<?> clazz,String methodName,Class<?>... parameterTypes){
  158. for(Class<?> c = clazz;c != null;c = c.getSuperclass() ){
  159. try {
  160. Method method = c.getDeclaredMethod(methodName, parameterTypes);
  161. return method;
  162. } catch (NoSuchMethodException e) {
  163. }
  164. }
  165. return null;
  166. }
  167. //调用成员方法
  168. public static Object invoke(Object obj,String methodName,Class<?>[] parameterTypes,Object[] values){
  169. Method method = getMethod(obj.getClass(), methodName, parameterTypes);
  170. method.setAccessible(true);
  171. try {
  172. Object invoke = method.invoke(obj, values);
  173. return invoke;
  174. } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
  175. e.printStackTrace();
  176. }
  177. return null;
  178. }
  179. //调用静态方法
  180. public static Object invoke(Class<?> clazz,String methodName,Class<?>[] parameterTypes,Object[] values){
  181. Method method = getMethod(clazz, methodName, parameterTypes);
  182. method.setAccessible(true);
  183. try {
  184. Object invoke = method.invoke(null, values);//静态方法直接填null,因为不需要对象去调用
  185. return invoke;
  186. } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
  187. e.printStackTrace();
  188. }
  189. return null;
  190. }
  191. }

2.利用反射获取class对象

  1. 方案一
  2. public class Test01 {
  3. public static void main(String[] args) throws ClassNotFoundException {
  4. //方式1:通过该类的对象获取class对象
  5. Student stu = new Student();
  6. Class<? extends Student> class1 = stu.getClass();
  7. //方式2:通过类名获取class对象
  8. Class<? extends Student> class2 = Student.class;
  9. //方式3:通过Class类的静态方法forName加上类的全路径获取class对象
  10. Class<?> class3 = Class.forName("com.gl.reflex01.Student");
  11. System.out.println(class1 == class2);//true
  12. System.out.println(class2 == class3);//true
  13. }
  14. }
  15. 方案二
  16. import java.io.IOException;
  17. import java.util.Properties;
  18. public class Test02 {
  19. public static void main(String[] args) throws IOException, ClassNotFoundException {
  20. Properties p = new Properties();
  21. p.load(Test02.class.getClassLoader().getResourceAsStream("classpath.properties"));
  22. String path = p.getProperty("path");
  23. Class<?> class1 = Class.forName(path);
  24. System.out.println(class1.getName());
  25. }
  26. }

3.利用反射操作属性 – Field

  1. public class Test03 {
  2. public static void main(String[] args) throws Exception {
  3. // Properties p = new Properties();
  4. // p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties"));
  5. // String path = p.getProperty("path");
  6. //
  7. // Class<?> clazz = Class.forName(path);
  8. //获取该类和父类的公有的属性对象
  9. // Field[] fields = clazz.getFields();
  10. // for (Field field : fields) {
  11. // System.out.println(field);
  12. // }
  13. //获取该类所有的属性对象
  14. // Field[] fields = clazz.getDeclaredFields();
  15. // for (Field field : fields) {
  16. // System.out.println(field);
  17. // }
  18. //获取该类及其父类所有的属性对象
  19. // List<Field> fields = ReflexUtil.getAllField(clazz);
  20. // for (Field field : fields) {
  21. // System.out.println(field);
  22. // }
  23. //获取该类指定的公有的属性对象
  24. // Field field = clazz.getField("classId");
  25. // System.out.println(field);
  26. //获取该类指定的属性对象
  27. // Field field = clazz.getDeclaredField("classId");
  28. // System.out.println(field);
  29. //获取该类及其父类指定的属性对象
  30. // Field field = ReflexUtil.getField(clazz, "name");
  31. // System.out.println(field);
  32. //利用反射机制去操作对象中的属性
  33. // Student stu = new Student();
  34. // Field fieldName = ReflexUtil.getField(clazz, "name");
  35. // fieldName.setAccessible(true);//设置修改权限
  36. // fieldName.set(stu, "关羽");
  37. // System.out.println(stu);
  38. //利用反射机制去操作对象中的属性 -- 封装成方法
  39. Student stu = new Student();
  40. ReflexUtil.setField(stu, "name", "关羽");
  41. ReflexUtil.setField(stu, "sex", '男');
  42. ReflexUtil.setField(stu, "age", 25);
  43. ReflexUtil.setField(stu, "classId", "2022");
  44. ReflexUtil.setField(stu, "id", "002");
  45. System.out.println(stu);
  46. }
  47. }

4.利用反射操作构造方法

  1. import java.util.Properties;
  2. public class Test04 {
  3. public static void main(String[] args) throws Exception {
  4. Properties p = new Properties();
  5. p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties"));
  6. String path = p.getProperty("path");
  7. @SuppressWarnings("unchecked")
  8. Class<Student> clazz = (Class<Student>) Class.forName(path);
  9. //获取该类公有的构造方法对象
  10. // Constructor<?>[] constructors = clazz.getConstructors();
  11. // for (Constructor<?> constructor : constructors) {
  12. // System.out.println(constructor);
  13. // }
  14. //获取该类所有的构造方法对象
  15. // Constructor<?>[] constructors = clazz.getDeclaredConstructors();
  16. // for (Constructor<?> constructor : constructors) {
  17. // System.out.println(constructor);
  18. // }
  19. //获取该类及其父类所有的构造方法对象
  20. // List<Constructor<?>> allConstructor = ReflexUtil.getAllConstructor(clazz);
  21. // for (Constructor<?> constructor : allConstructor) {
  22. // System.out.println(constructor);
  23. // }
  24. //获取该类指定的公有的构造方法对象并创建该类对象 -- 无参构造
  25. // Constructor<?> constructor = clazz.getConstructor();//获取公有的无参构造
  26. // Student stu = (Student) constructor.newInstance();//利用构造方法对象创建该类的对象
  27. // System.out.println(stu);
  28. //直接利用无参构造创建对象
  29. // Student stu = (Student) clazz.newInstance();//底层:获取该类的无参构造对象,并创建该类的对象
  30. // System.out.println(stu);
  31. //获取该类指定的公有的构造方法对象并创建该类对象 -- 有参构造
  32. // Constructor<?> constructor = clazz.getConstructor(String.class,char.class,int.class,String.class,String.class);//获取公有的有参构造
  33. // Student stu = (Student) constructor.newInstance("刘备",'男',23,"2022","001");//利用构造方法对象创建该类的对象
  34. // System.out.println(stu);
  35. //获取该类指定的构造方法对象并创建该类对象 -- 私有的有参构造
  36. // Constructor<?> constructor = clazz.getDeclaredConstructor(String.class,String.class);//获取有参构造
  37. // constructor.setAccessible(true);//设置修改权限
  38. // Student stu = (Student) constructor.newInstance("2022","001");//利用构造方法对象创建该类的对象
  39. // System.out.println(stu);
  40. //利用反射机制去创建该类的对象 -- 封装成方法
  41. Student stu1 = ReflexUtil.newInstance(clazz, null, null);
  42. System.out.println(stu1);
  43. Student stu2 = ReflexUtil.newInstance(clazz,new Class[]{
  44. String.class,char.class,int.class,String.class,String.class},new Object[]{
  45. "刘备",'男',23,"2022","001"});
  46. System.out.println(stu2);
  47. }
  48. }

5.利用反射操作方法

  1. import java.util.Properties;
  2. public class Test05 {
  3. public static void main(String[] args) throws Exception {
  4. Properties p = new Properties();
  5. p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties"));
  6. String path = p.getProperty("path");
  7. @SuppressWarnings("unchecked")
  8. Class<Student> clazz = (Class<Student>) Class.forName(path);
  9. //获取该类以及父类公有的方法对象
  10. // Method[] methods = clazz.getMethods();
  11. // for (Method method : methods) {
  12. // System.out.println(method);
  13. // }
  14. //获取该类所有的方法对象
  15. // Method[] methods = clazz.getDeclaredMethods();
  16. // for (Method method : methods) {
  17. // System.out.println(method);
  18. // }
  19. //获取该类及其父类所有的方法对象
  20. // List<Method> list = ReflexUtil.getAllMethod(clazz);
  21. // for (Method method : list) {
  22. // System.out.println(method);
  23. // }
  24. //调用公有的方法 -- 无参数的方法
  25. // Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"});
  26. // Method method = clazz.getMethod("getClassId");
  27. // Object invoke = method.invoke(stu);
  28. // System.out.println("返回值:" + invoke);
  29. //调用公有的方法 -- 有参数的方法
  30. // Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"});
  31. // Method method = clazz.getMethod("setClassId",String.class);
  32. // Object invoke = method.invoke(stu,"2212");
  33. // System.out.println("返回值:" + invoke);
  34. // System.out.println(stu);
  35. //调用私有的方法
  36. // Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"});
  37. // Method method = clazz.getDeclaredMethod("method01", String.class);
  38. // method.setAccessible(true);
  39. // Object invoke = method.invoke(stu, "abc");
  40. // System.out.println("返回值:" + invoke);
  41. //调用方法 -- 封装方法
  42. // Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"});
  43. // Object invoke = ReflexUtil.invoke(stu, "method01", new Class[]{String.class}, new Object[]{"abc"});
  44. // System.out.println("返回值:" + invoke);
  45. //调用静态方法
  46. Object invoke = ReflexUtil.invoke(clazz, "method02", null,null);
  47. System.out.println("返回值:" + invoke);
  48. }
  49. }

6.利用反射操作泛型

注意:类上的泛型是获取不到的

  1. import java.lang.reflect.Method;
  2. import java.lang.reflect.ParameterizedType;
  3. import java.lang.reflect.Type;
  4. import java.util.ArrayList;
  5. import java.util.HashMap;
  6. public class Test06 {
  7. public static void main(String[] args) throws Exception {
  8. Class<?> clazz = Test06.class;
  9. Method method = clazz.getDeclaredMethod("method", ArrayList.class,HashMap.class);
  10. //获取参数上的泛型
  11. Type[] genericParameterTypes = method.getGenericParameterTypes();//获取参数类型
  12. for (Type type : genericParameterTypes) {
  13. ParameterizedType pt = (ParameterizedType) type;//把type强转为参数类型
  14. Type[] actualTypeArguments = pt.getActualTypeArguments();//获取参数类型上的泛型并返回泛型数组(为什么返回的是数组?因为一个参数上有可能有多个泛型)
  15. for (Type t : actualTypeArguments) {
  16. System.out.println(t);
  17. }
  18. }
  19. System.out.println("-------------");
  20. //获取返回值上的泛型
  21. Type genericReturnType = method.getGenericReturnType();
  22. ParameterizedType pt = (ParameterizedType)genericReturnType;
  23. Type[] actualTypeArguments = pt.getActualTypeArguments();//获取返回值类型上的泛型并返回泛型数组(为什么返回的是数组?因为一个参数上有可能有多个泛型)
  24. for (Type type : actualTypeArguments) {
  25. System.out.println(type);
  26. }
  27. }
  28. public HashMap<String, Integer> method(ArrayList<String> list,HashMap<String, Integer> map){
  29. return null;
  30. }
  31. }

7.利用反射操作数组

  1. Arrays -- 数组的工具类
  2. Array --- 数组的反射类
  3. import java.lang.reflect.Array;
  4. public class Test07 {
  5. public static void main(String[] args) throws Exception {
  6. //创建数组
  7. int[] is = (int[]) Array.newInstance(int.class, 5);
  8. //获取数组的长度
  9. System.out.println("获取数组的长度:" + Array.getLength(is));//5
  10. //通过下标设置元素
  11. Array.set(is, 2, 888);
  12. //遍历数组
  13. for(int i = 0;i<Array.getLength(is);i++){
  14. //通过下标获取元素
  15. Object element = Array.get(is, i);
  16. System.out.println(element);
  17. }
  18. }
  19. }

8.反射机制 之 扩展运用封装代码

  1. public class Person {
  2. private String name;
  3. private char sex;
  4. private int age;
  5. public Person() {
  6. }
  7. public Person(String name, char sex, int age) {
  8. this.name = name;
  9. this.sex = sex;
  10. this.age = age;
  11. }
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public char getSex() {
  19. return sex;
  20. }
  21. public void setSex(char sex) {
  22. this.sex = sex;
  23. }
  24. public int getAge() {
  25. return age;
  26. }
  27. public void setAge(int age) {
  28. this.age = age;
  29. }
  30. @Override
  31. public String toString() {
  32. return "Person [names=" + name + ", sex=" + sex + ", age=" + age + "]";
  33. }
  34. }
  35. import java.lang.reflect.Constructor;
  36. import java.lang.reflect.Field;
  37. import java.lang.reflect.InvocationTargetException;
  38. import java.lang.reflect.Method;
  39. import java.util.ArrayList;
  40. import java.util.Collections;
  41. import java.util.List;
  42. //反射工具类
  43. public class ReflexUtil {
  44. //获取该类及其父类所有的属性对象
  45. public static List<Field> getAllField(Class<?> clazz){
  46. List<Field> list = new ArrayList<>();
  47. for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
  48. Field[] fields = c.getDeclaredFields();
  49. Collections.addAll(list, fields);
  50. }
  51. return list;
  52. }
  53. //获取该类及其父类指定的属性对象
  54. public static Field getField(Class<?> clazz,String fieldName){
  55. for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
  56. try {
  57. Field field = c.getDeclaredField(fieldName);
  58. return field;
  59. } catch (NoSuchFieldException e) {
  60. //如果该类中找不到属性就会出现该异常
  61. }
  62. }
  63. return null;
  64. }
  65. //设置对象中的属性
  66. public static void setField(Object obj,String fieldName,Object value){
  67. Field field = getField(obj.getClass(), fieldName);
  68. field.setAccessible(true);
  69. try {
  70. field.set(obj, value);
  71. } catch (IllegalArgumentException e) {
  72. e.printStackTrace();
  73. } catch (IllegalAccessException e) {
  74. e.printStackTrace();
  75. }
  76. }
  77. //获取该类及其父类所有的构造对象
  78. public static List<Constructor<?>> getAllConstructor(Class<?> clazz){
  79. List<Constructor<?>> list = new ArrayList<>();
  80. for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
  81. Constructor<?>[] constructors = c.getDeclaredConstructors();
  82. Collections.addAll(list, constructors);
  83. }
  84. return list;
  85. }
  86. //创建该类的对象
  87. public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] values){
  88. try {
  89. Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
  90. constructor.setAccessible(true);
  91. T t = constructor.newInstance(values);
  92. return t;
  93. } catch (NoSuchMethodException e) {
  94. e.printStackTrace();
  95. } catch (SecurityException e) {
  96. e.printStackTrace();
  97. } catch (InstantiationException e) {
  98. e.printStackTrace();
  99. } catch (IllegalAccessException e) {
  100. e.printStackTrace();
  101. } catch (IllegalArgumentException e) {
  102. e.printStackTrace();
  103. } catch (InvocationTargetException e) {
  104. e.printStackTrace();
  105. }
  106. return null;
  107. }
  108. //获取该类及其父类所有的方法对象
  109. public static List<Method> getAllMethod(Class<?> clazz){
  110. List<Method> list = new ArrayList<>();
  111. for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
  112. Method[] methods = c.getDeclaredMethods();
  113. Collections.addAll(list, methods);
  114. }
  115. return list;
  116. }
  117. //获取指定的方法对象
  118. public static Method getMethod(Class<?> clazz,String methodName,Class<?>... parameterTypes){
  119. for(Class<?> c = clazz;c != null;c = c.getSuperclass() ){
  120. try {
  121. Method method = c.getDeclaredMethod(methodName, parameterTypes);
  122. return method;
  123. } catch (NoSuchMethodException e) {
  124. }
  125. }
  126. return null;
  127. }
  128. //调用成员方法
  129. public static Object invoke(Object obj,String methodName,Class<?>[] parameterTypes,Object[] values){
  130. Method method = getMethod(obj.getClass(), methodName, parameterTypes);
  131. method.setAccessible(true);
  132. try {
  133. Object invoke = method.invoke(obj, values);
  134. return invoke;
  135. } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
  136. e.printStackTrace();
  137. }
  138. return null;
  139. }
  140. //调用静态方法
  141. public static Object invoke(Class<?> clazz,String methodName,Class<?>[] parameterTypes,Object[] values){
  142. Method method = getMethod(clazz, methodName, parameterTypes);
  143. method.setAccessible(true);
  144. try {
  145. Object invoke = method.invoke(null, values);//静态方法直接填null,因为不需要对象去调用
  146. return invoke;
  147. } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
  148. e.printStackTrace();
  149. }
  150. return values;
  151. }
  152. }
  153. public class Student extends Person{
  154. private String classId;
  155. private String id;
  156. public Student() {
  157. }
  158. public Student(String name, char sex, int age, String classId, String id) {
  159. super(name, sex, age);
  160. this.classId = classId;
  161. this.id = id;
  162. }
  163. public String getClassId() {
  164. return classId;
  165. }
  166. public void setClassId(String classId) {
  167. this.classId = classId;
  168. }
  169. public String getId() {
  170. return id;
  171. }
  172. public void setId(String id) {
  173. this.id = id;
  174. }
  175. // private String method01(String str){
  176. // System.out.println("私有的方法 :" + str);
  177. // return "用良心做教育";
  178. //}
  179. @Override
  180. public String toString() {
  181. return "Student [classId=" + classId + ", id=" + id + ", getName()=" + getName() + ", getSex()=" + getSex()
  182. + ", getAge()=" + getAge() + "]";
  183. }
  184. public static void method02(){
  185. System.out.println("静态的方法");
  186. }
  187. }

9.反射机制 之 扩展属性的运用

  1. import java.lang.reflect.Field;
  2. import java.lang.reflect.Modifier;
  3. import java.util.Properties;
  4. public class Test01 {
  5. public static void main(String[] args) throws Exception {
  6. Properties p = new Properties();
  7. p.load(Test01.class.getClassLoader().getResourceAsStream("classpath.properties"));
  8. String path = p.getProperty("path");
  9. Class<?> clazz = Class.forName(path);
  10. //获取学生类中的name属性
  11. Field field = ReflexUtil.getField(clazz, "name");
  12. //获取属性参数值
  13. int modifiers = field.getModifiers();
  14. System.out.println("判断属性是否是私有化的:" + Modifier.isPrivate(modifiers));
  15. System.out.println("判断属性是否是Protected的:" + Modifier.isProtected(modifiers));
  16. System.out.println("判断属性是否是公有的:" + Modifier.isPublic(modifiers));
  17. System.out.println("判断属性是否是静态的:" + Modifier.isStatic(modifiers));
  18. System.out.println("判断属性是否是常量的:" + Modifier.isFinal(modifiers));
  19. }
  20. }

10.反射机制 之 扩展方法的运用

  1. import java.lang.reflect.Method;
  2. import java.lang.reflect.Modifier;
  3. import java.util.Properties;
  4. public class Test02 {
  5. @SuppressWarnings("all")
  6. public static void main(String[] args) throws Exception {
  7. Properties p = new Properties();
  8. p.load(Test02.class.getClassLoader().getResourceAsStream("classpath.properties"));
  9. String path = p.getProperty("path");
  10. Class<?> clazz = Class.forName(path);
  11. //获取学生类中的method02
  12. Method method = ReflexUtil.getMethod(clazz, "method02",null);
  13. //获取方法参数值
  14. int modifiers = method.getModifiers();
  15. System.out.println("判断方法是否是私有化的:" + Modifier.isPrivate(modifiers));
  16. System.out.println("判断方法是否是Protected的:" + Modifier.isProtected(modifiers));
  17. System.out.println("判断方法是否是公有的:" + Modifier.isPublic(modifiers));
  18. System.out.println("判断方法是否是静态的:" + Modifier.isStatic(modifiers));
  19. System.out.println("判断方法是否不可重写的:" + Modifier.isFinal(modifiers));
  20. System.out.println("判断方法是否同步的:" + Modifier.isSynchronized(modifiers));
  21. System.out.println("判断方法是否抽象的:" + Modifier.isAbstract(modifiers));
  22. }
  23. }

11.反射案例之万能数组扩容/复制

  1. import java.lang.reflect.Array;
  2. import java.util.Arrays;
  3. public class Test01 {
  4. public static void main(String[] args) {
  5. int[] is = {
  6. 1,2,3,4,5};
  7. int[] copy1 = copy(is,10);
  8. System.out.println(Arrays.toString(copy1));
  9. System.out.println("---------");
  10. String[] names = {
  11. "后裔","狄仁杰","李元芳","孙尚香"};
  12. String[] copy2 = copy(names,10);
  13. System.out.println(Arrays.toString(copy2));
  14. }
  15. public static <T> T copy(T t,int newLength){
  16. //获取数组的class对象
  17. Class<? extends Object> clazz = t.getClass();
  18. //获取数组元素类型的class对象
  19. Class<?> elementClazz = clazz.getComponentType();
  20. //创建数组
  21. @SuppressWarnings("unchecked")
  22. T arr = (T) Array.newInstance(elementClazz, newLength);
  23. //遍历原数组
  24. for (int i = 0; i < Array.getLength(t); i++) {
  25. //获取指定下标上的元素
  26. Object element = Array.get(t, i);
  27. //将元素设置给新数组
  28. Array.set(arr, i, element);
  29. }
  30. return arr;
  31. }
  32. }

12.反射案例 之 逻辑与业务分离的思想

  • 业务场景:获取数据
  • 分析:
  • 获取本地数据 – 代码
  • 获取网络数据 – 代码
  • 获取其他数据 – 代码

    import java.util.List;
    import java.util.Scanner;

    public class Test01 {

  1. public static void main(String[] args) {
  2. Scanner scan = new Scanner(System.in);
  3. printMenu();
  4. int num = scan.nextInt();
  5. DataSource dataSource = getDataSourceObj(num);
  6. dataSource.getDataSource();
  7. scan.close();
  8. }
  9. public static DataSource getDataSourceObj(int num){
  10. List<String> classlist = DataContainer.classList;
  11. String classPath = classlist.get(num-1);
  12. try {
  13. Class<?> clazz = Class.forName(classPath);
  14. DataSource dataSource = (DataSource) clazz.newInstance();
  15. return dataSource;
  16. } catch (ClassNotFoundException e) {
  17. e.printStackTrace();
  18. } catch (InstantiationException e) {
  19. e.printStackTrace();
  20. } catch (IllegalAccessException e) {
  21. e.printStackTrace();
  22. }
  23. return null;
  24. }
  25. private static void printMenu() {
  26. List<String> menulist = DataContainer.menuList;
  27. System.out.println("请选择获取数据的方式:");
  28. for (String str : menulist) {
  29. System.out.println(str);
  30. }
  31. }
  32. }
  33. import java.io.IOException;
  34. import java.util.ArrayList;
  35. import java.util.List;
  36. import java.util.Properties;
  37. public class DataContainer {
  38. public static final List<String> menuList;
  39. public static final List<String> classList;
  40. static{
  41. //初始化菜单集合
  42. menuList = new ArrayList<>();
  43. Properties menuProperties = new Properties();
  44. try {
  45. menuProperties.load(DataContainer.class.getClassLoader().getResourceAsStream("menuConfig.properties"));
  46. } catch (IOException e) {
  47. e.printStackTrace();
  48. }
  49. String menu = menuProperties.getProperty("menu");
  50. String[] menuSplit = menu.split(",");
  51. for (String str : menuSplit) {
  52. menuList.add(str);
  53. }
  54. //初始化类路径集合
  55. classList = new ArrayList<>();
  56. Properties classProperties = new Properties();
  57. try {
  58. classProperties.load(DataContainer.class.getClassLoader().getResourceAsStream("classConfig.properties"));
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. }
  62. String path = classProperties.getProperty("path");
  63. String[] pathSplit = path.split(",");
  64. for (String str : pathSplit) {
  65. classList.add(str);
  66. }
  67. }
  68. }
  69. public abstract class DataSource {
  70. public abstract void getDataSource();
  71. }
  72. public class LocalDataSource extends DataSource{
  73. @Override
  74. public void getDataSource() {
  75. System.out.println("执行获取本地数据的代码...");
  76. }
  77. }
  78. public class NetworkDataSource extends DataSource{
  79. @Override
  80. public void getDataSource() {
  81. System.out.println("执行获取网络数据的代码...");
  82. }
  83. }
  84. public class OtherDataSource extends DataSource{
  85. @Override
  86. public void getDataSource() {
  87. System.out.println("执行获取其他数据的代码...");
  88. }
  89. }

13.反射案例 之 获取注解信息

  1. import java.lang.reflect.Field;
  2. public class Test01 {
  3. public static void main(String[] args) {
  4. Student stu = new Student("刘备", '男', 23);
  5. Class<? extends Student> clazz = stu.getClass();
  6. //获取类上注解的信息
  7. TableInfo tableInfoAnnotation = clazz.getAnnotation(TableInfo.class);
  8. String tableName = tableInfoAnnotation.value();
  9. System.out.println(tableName);
  10. //获取属性上注解的信息
  11. Field[] fields = clazz.getDeclaredFields();
  12. for (Field field : fields) {
  13. FieldInfo fieldInfoAnnotation = field.getAnnotation(FieldInfo.class);
  14. String name = fieldInfoAnnotation.name();
  15. String type = fieldInfoAnnotation.type();
  16. int length = fieldInfoAnnotation.length();
  17. Object value = null;
  18. try {
  19. field.setAccessible(true);
  20. value = field.get(stu);
  21. } catch (IllegalArgumentException e) {
  22. e.printStackTrace();
  23. } catch (IllegalAccessException e) {
  24. e.printStackTrace();
  25. }
  26. System.out.println(name + " -- " + type + " -- " + length + " -- " + value);
  27. }
  28. //insert into s_student(s_name,s_sex,s_age) values("刘备","男",23)
  29. }
  30. }
  31. @TableInfo("s_student")
  32. public class Student {
  33. @FieldInfo(name="s_name",type="varchar",length=32)
  34. private String name;
  35. @FieldInfo(name="s_sex",type="varchar",length=32)
  36. private char sex;
  37. @FieldInfo(name="s_age",type="int",length=3)
  38. private int age;
  39. public Student() {
  40. }
  41. public Student(String name, char sex, int age) {
  42. this.name = name;
  43. this.sex = sex;
  44. this.age = age;
  45. }
  46. public String getName() {
  47. return name;
  48. }
  49. public void setName(String name) {
  50. this.name = name;
  51. }
  52. public char getSex() {
  53. return sex;
  54. }
  55. public void setSex(char sex) {
  56. this.sex = sex;
  57. }
  58. public int getAge() {
  59. return age;
  60. }
  61. public void setAge(int age) {
  62. this.age = age;
  63. }
  64. @Override
  65. public String toString() {
  66. return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]";
  67. }
  68. }
  69. import java.lang.annotation.ElementType;
  70. import java.lang.annotation.Retention;
  71. import java.lang.annotation.RetentionPolicy;
  72. import java.lang.annotation.Target;
  73. @Target(ElementType.TYPE)
  74. @Retention(RetentionPolicy.RUNTIME)
  75. public @interface TableInfo {
  76. String value();
  77. }
  78. import java.lang.annotation.ElementType;
  79. import java.lang.annotation.Retention;
  80. import java.lang.annotation.RetentionPolicy;
  81. import java.lang.annotation.Target;
  82. @Target(ElementType.FIELD)
  83. @Retention(RetentionPolicy.RUNTIME)
  84. public @interface FieldInfo {
  85. String name();
  86. String type();
  87. int length();
  88. }

发表评论

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

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

相关阅读

    相关 注解反射

    注解(Annotation)是Java中的一种元数据,它提供了一种为程序元素(类、方法、变量等)添加元数据的方式。注解可以用来描述程序元素的特性、用途和约束条件等信息。Java

    相关 注解反射

    注解(Annotation)是Java中的一种元数据,它提供了一种为程序元素(类、方法、变量等)添加元数据的方式。注解可以用来描述程序元素的特性、用途和约束条件等信息。Java

    相关 注解反射

    注解 什么是注解 Annotation(注解)是从JDK5.0开始引入的新技术 注解可以被其他程序(如:编译器等)读取,不是程序本身,可以对程序做出解释

    相关 反射注解

    反射与注解 一、反射 1. 使用反射机制可以动态的获取当前class的信息,比如方法的信息、注解信息、方法的参数、属性 2. 反射目的:方便开发者对框架的拓展,