注解与反射机制 阳光穿透心脏的1/2处 2024-04-20 11:20 17阅读 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:说明子类可以继承父类中的该注解 @MyAnnotation02 public class Test01<@MyAnnotation02 T> { @MyAnnotation02 public String name; @MyAnnotation02 public Test01() { } @MyAnnotation01 @MyAnnotation02 @MyAnnotation03("aaa") @MyAnnotation04 @MyAnnotation05(name = "aaa") @MyAnnotation06(names = { "aaa","bbb"}) @MyAnnotation07(names={ "aaa","bbb"},username="撕裂的忧伤") public void method(String str){ @MyAnnotation02 int i = 100; System.out.println(i); } } import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解只能在方法上使用,并且没有参数 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation01 { } import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解可以在方法、类、构造方法、属性、局部变量、泛型上使用,并且没有参数 */ @Target({ METHOD,TYPE,CONSTRUCTOR,FIELD,LOCAL_VARIABLE,TYPE_PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation02 { } import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解可以在方法上使用,并且有一个参数 */ @Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation03 { String value(); } import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解可以在方法上使用,并且有一个参数 */ @Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation04 { String value() default "abc";//设置默认值 } import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解可以在方法上使用,并且有一个参数 */ @Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation05 { String name(); } import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解可以在方法上使用,并且有一个参数 */ @Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation06 { String[] names(); } import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 该注解可以在方法上使用,并且有一个参数 */ @Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation07 { String[] names(); String username(); String password() default "00000000"; } #### 8.自定义注解 #### > 使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口 > > 分析: > > @interface用来声明一个注解,格式:public @interface注解名\{定义内容\} > > 其中的每一个方法实际上是声明了一个配置参数. > > 方法的名称就是参数的名称. > > 返回值类型就是参数的类型(返回值只能是基本类型、Class、String、enum) > > 可以通过default来声明参数的默认值 > > 如果只有一个参数成员,一般参数名为value() > > 注解元素必須要有值,我们定义注解元素时,经常使用空字符串.0作为默认值 import java.util.ArrayList; public class test01 { //重写的注解 @Override public boolean equals(Object obj) { return super.equals(obj); } //过时的注解 @Deprecated public void method01(){ } //镇压警告的注解 @SuppressWarnings("all") public void method02(){ ArrayList list = new ArrayList(); list.add(134); list.add("abc"); } } ### 二、反射机制 ### #### 1.含义: #### > 使用到一个类,该类的class文件会加载到方法区,并且在堆中创建该类的class对象,class对象作为class文件的访问入口,反射就是获取class对象,拿到class对象就可以访问class文件(换言之,可以对该类为所欲为-属性、构造方法、方法) public class Student extends Person{ private String classId; private String id; public Student() { } // private Student(String classId, String id) { // this.classId = classId; // this.id = id; // } public Student(String name, char sex, int age, String classId, String id) { super(name, sex, age); this.classId = classId; this.id = id; } public String getClassId() { return classId; } public void setClassId(String classId) { this.classId = classId; } public String getId() { return id; } public void setId(String id) { this.id = id; } @Override public String toString() { return "Student [classId=" + classId + ", id=" + id + ", getName()=" + getName() + ", getSex()=" + getSex() + ", getAge()=" + getAge() + "]"; } // private String method01(String str){ // System.out.println("私有的方法 :" + str); // return "用良心做教育"; // } public static void method02(){ System.out.println("静态的方法"); } } public class Person { private String name; private char sex; private int age; public Person() { } public Person(String name, char sex, int age) { this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]"; } } import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; //反射工具类 public class ReflexUtil { //获取该类及其父类所有的属性对象 public static List<Field> getAllField(Class<?> clazz){ List<Field> list = new ArrayList<>(); for (Class<?> c = clazz;c != null;c = c.getSuperclass()) { Field[] fields = c.getDeclaredFields(); Collections.addAll(list, fields); } return list; } //获取该类及其父类指定的属性对象 public static Field getField(Class<?> clazz,String fieldName){ for (Class<?> c = clazz;c != null;c = c.getSuperclass()) { try { Field field = c.getDeclaredField(fieldName); return field; } catch (NoSuchFieldException e) { //如果该类中找不到属性就会出现该异常 } } return null; } //设置对象中的属性 public static void setField(Object obj,String fieldName,Object value){ Field field = getField(obj.getClass(), fieldName); field.setAccessible(true); try { field.set(obj, value); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } //获取该类及其父类所有的构造对象 public static List<Constructor<?>> getAllConstructor(Class<?> clazz){ List<Constructor<?>> list = new ArrayList<>(); for (Class<?> c = clazz;c != null;c = c.getSuperclass()) { Constructor<?>[] constructors = c.getDeclaredConstructors(); Collections.addAll(list, constructors); } return list; } //创建该类的对象 public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] values){ try { Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes); constructor.setAccessible(true); T t = constructor.newInstance(values); return t; } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } //获取该类及其父类所有的方法对象 public static List<Method> getAllMethod(Class<?> clazz){ List<Method> list = new ArrayList<>(); for (Class<?> c = clazz;c != null;c = c.getSuperclass()) { Method[] methods = c.getDeclaredMethods(); Collections.addAll(list, methods); } return list; } //获取指定的方法对象 public static Method getMethod(Class<?> clazz,String methodName,Class<?>... parameterTypes){ for(Class<?> c = clazz;c != null;c = c.getSuperclass() ){ try { Method method = c.getDeclaredMethod(methodName, parameterTypes); return method; } catch (NoSuchMethodException e) { } } return null; } //调用成员方法 public static Object invoke(Object obj,String methodName,Class<?>[] parameterTypes,Object[] values){ Method method = getMethod(obj.getClass(), methodName, parameterTypes); method.setAccessible(true); try { Object invoke = method.invoke(obj, values); return invoke; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } return null; } //调用静态方法 public static Object invoke(Class<?> clazz,String methodName,Class<?>[] parameterTypes,Object[] values){ Method method = getMethod(clazz, methodName, parameterTypes); method.setAccessible(true); try { Object invoke = method.invoke(null, values);//静态方法直接填null,因为不需要对象去调用 return invoke; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } return null; } } #### 2.利用反射获取class对象 #### 方案一 public class Test01 { public static void main(String[] args) throws ClassNotFoundException { //方式1:通过该类的对象获取class对象 Student stu = new Student(); Class<? extends Student> class1 = stu.getClass(); //方式2:通过类名获取class对象 Class<? extends Student> class2 = Student.class; //方式3:通过Class类的静态方法forName加上类的全路径获取class对象 Class<?> class3 = Class.forName("com.gl.reflex01.Student"); System.out.println(class1 == class2);//true System.out.println(class2 == class3);//true } } 方案二 import java.io.IOException; import java.util.Properties; public class Test02 { public static void main(String[] args) throws IOException, ClassNotFoundException { Properties p = new Properties(); p.load(Test02.class.getClassLoader().getResourceAsStream("classpath.properties")); String path = p.getProperty("path"); Class<?> class1 = Class.forName(path); System.out.println(class1.getName()); } } #### 3.利用反射操作属性 – Field #### public class Test03 { public static void main(String[] args) throws Exception { // Properties p = new Properties(); // p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties")); // String path = p.getProperty("path"); // // Class<?> clazz = Class.forName(path); //获取该类和父类的公有的属性对象 // Field[] fields = clazz.getFields(); // for (Field field : fields) { // System.out.println(field); // } //获取该类所有的属性对象 // Field[] fields = clazz.getDeclaredFields(); // for (Field field : fields) { // System.out.println(field); // } //获取该类及其父类所有的属性对象 // List<Field> fields = ReflexUtil.getAllField(clazz); // for (Field field : fields) { // System.out.println(field); // } //获取该类指定的公有的属性对象 // Field field = clazz.getField("classId"); // System.out.println(field); //获取该类指定的属性对象 // Field field = clazz.getDeclaredField("classId"); // System.out.println(field); //获取该类及其父类指定的属性对象 // Field field = ReflexUtil.getField(clazz, "name"); // System.out.println(field); //利用反射机制去操作对象中的属性 // Student stu = new Student(); // Field fieldName = ReflexUtil.getField(clazz, "name"); // fieldName.setAccessible(true);//设置修改权限 // fieldName.set(stu, "关羽"); // System.out.println(stu); //利用反射机制去操作对象中的属性 -- 封装成方法 Student stu = new Student(); ReflexUtil.setField(stu, "name", "关羽"); ReflexUtil.setField(stu, "sex", '男'); ReflexUtil.setField(stu, "age", 25); ReflexUtil.setField(stu, "classId", "2022"); ReflexUtil.setField(stu, "id", "002"); System.out.println(stu); } } #### 4.利用反射操作构造方法 #### import java.util.Properties; public class Test04 { public static void main(String[] args) throws Exception { Properties p = new Properties(); p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties")); String path = p.getProperty("path"); @SuppressWarnings("unchecked") Class<Student> clazz = (Class<Student>) Class.forName(path); //获取该类公有的构造方法对象 // Constructor<?>[] constructors = clazz.getConstructors(); // for (Constructor<?> constructor : constructors) { // System.out.println(constructor); // } //获取该类所有的构造方法对象 // Constructor<?>[] constructors = clazz.getDeclaredConstructors(); // for (Constructor<?> constructor : constructors) { // System.out.println(constructor); // } //获取该类及其父类所有的构造方法对象 // List<Constructor<?>> allConstructor = ReflexUtil.getAllConstructor(clazz); // for (Constructor<?> constructor : allConstructor) { // System.out.println(constructor); // } //获取该类指定的公有的构造方法对象并创建该类对象 -- 无参构造 // Constructor<?> constructor = clazz.getConstructor();//获取公有的无参构造 // Student stu = (Student) constructor.newInstance();//利用构造方法对象创建该类的对象 // System.out.println(stu); //直接利用无参构造创建对象 // Student stu = (Student) clazz.newInstance();//底层:获取该类的无参构造对象,并创建该类的对象 // System.out.println(stu); //获取该类指定的公有的构造方法对象并创建该类对象 -- 有参构造 // Constructor<?> constructor = clazz.getConstructor(String.class,char.class,int.class,String.class,String.class);//获取公有的有参构造 // Student stu = (Student) constructor.newInstance("刘备",'男',23,"2022","001");//利用构造方法对象创建该类的对象 // System.out.println(stu); //获取该类指定的构造方法对象并创建该类对象 -- 私有的有参构造 // Constructor<?> constructor = clazz.getDeclaredConstructor(String.class,String.class);//获取有参构造 // constructor.setAccessible(true);//设置修改权限 // Student stu = (Student) constructor.newInstance("2022","001");//利用构造方法对象创建该类的对象 // System.out.println(stu); //利用反射机制去创建该类的对象 -- 封装成方法 Student stu1 = ReflexUtil.newInstance(clazz, null, null); System.out.println(stu1); Student stu2 = ReflexUtil.newInstance(clazz,new Class[]{ String.class,char.class,int.class,String.class,String.class},new Object[]{ "刘备",'男',23,"2022","001"}); System.out.println(stu2); } } #### 5.利用反射操作方法 #### import java.util.Properties; public class Test05 { public static void main(String[] args) throws Exception { Properties p = new Properties(); p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties")); String path = p.getProperty("path"); @SuppressWarnings("unchecked") Class<Student> clazz = (Class<Student>) Class.forName(path); //获取该类以及父类公有的方法对象 // Method[] methods = clazz.getMethods(); // for (Method method : methods) { // System.out.println(method); // } //获取该类所有的方法对象 // Method[] methods = clazz.getDeclaredMethods(); // for (Method method : methods) { // System.out.println(method); // } //获取该类及其父类所有的方法对象 // List<Method> list = ReflexUtil.getAllMethod(clazz); // for (Method method : list) { // System.out.println(method); // } //调用公有的方法 -- 无参数的方法 // Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"}); // Method method = clazz.getMethod("getClassId"); // Object invoke = method.invoke(stu); // System.out.println("返回值:" + invoke); //调用公有的方法 -- 有参数的方法 // Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"}); // Method method = clazz.getMethod("setClassId",String.class); // Object invoke = method.invoke(stu,"2212"); // System.out.println("返回值:" + invoke); // System.out.println(stu); //调用私有的方法 // Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"}); // Method method = clazz.getDeclaredMethod("method01", String.class); // method.setAccessible(true); // Object invoke = method.invoke(stu, "abc"); // System.out.println("返回值:" + invoke); //调用方法 -- 封装方法 // Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"}); // Object invoke = ReflexUtil.invoke(stu, "method01", new Class[]{String.class}, new Object[]{"abc"}); // System.out.println("返回值:" + invoke); //调用静态方法 Object invoke = ReflexUtil.invoke(clazz, "method02", null,null); System.out.println("返回值:" + invoke); } } #### 6.利用反射操作泛型 #### > 注意:类上的泛型是获取不到的 import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; public class Test06 { public static void main(String[] args) throws Exception { Class<?> clazz = Test06.class; Method method = clazz.getDeclaredMethod("method", ArrayList.class,HashMap.class); //获取参数上的泛型 Type[] genericParameterTypes = method.getGenericParameterTypes();//获取参数类型 for (Type type : genericParameterTypes) { ParameterizedType pt = (ParameterizedType) type;//把type强转为参数类型 Type[] actualTypeArguments = pt.getActualTypeArguments();//获取参数类型上的泛型并返回泛型数组(为什么返回的是数组?因为一个参数上有可能有多个泛型) for (Type t : actualTypeArguments) { System.out.println(t); } } System.out.println("-------------"); //获取返回值上的泛型 Type genericReturnType = method.getGenericReturnType(); ParameterizedType pt = (ParameterizedType)genericReturnType; Type[] actualTypeArguments = pt.getActualTypeArguments();//获取返回值类型上的泛型并返回泛型数组(为什么返回的是数组?因为一个参数上有可能有多个泛型) for (Type type : actualTypeArguments) { System.out.println(type); } } public HashMap<String, Integer> method(ArrayList<String> list,HashMap<String, Integer> map){ return null; } } #### 7.利用反射操作数组 #### Arrays -- 数组的工具类 Array --- 数组的反射类 import java.lang.reflect.Array; public class Test07 { public static void main(String[] args) throws Exception { //创建数组 int[] is = (int[]) Array.newInstance(int.class, 5); //获取数组的长度 System.out.println("获取数组的长度:" + Array.getLength(is));//5 //通过下标设置元素 Array.set(is, 2, 888); //遍历数组 for(int i = 0;i<Array.getLength(is);i++){ //通过下标获取元素 Object element = Array.get(is, i); System.out.println(element); } } } #### 8.反射机制 之 扩展运用封装代码 #### public class Person { private String name; private char sex; private int age; public Person() { } public Person(String name, char sex, int age) { this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [names=" + name + ", sex=" + sex + ", age=" + age + "]"; } } import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; //反射工具类 public class ReflexUtil { //获取该类及其父类所有的属性对象 public static List<Field> getAllField(Class<?> clazz){ List<Field> list = new ArrayList<>(); for (Class<?> c = clazz;c != null;c = c.getSuperclass()) { Field[] fields = c.getDeclaredFields(); Collections.addAll(list, fields); } return list; } //获取该类及其父类指定的属性对象 public static Field getField(Class<?> clazz,String fieldName){ for (Class<?> c = clazz;c != null;c = c.getSuperclass()) { try { Field field = c.getDeclaredField(fieldName); return field; } catch (NoSuchFieldException e) { //如果该类中找不到属性就会出现该异常 } } return null; } //设置对象中的属性 public static void setField(Object obj,String fieldName,Object value){ Field field = getField(obj.getClass(), fieldName); field.setAccessible(true); try { field.set(obj, value); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } //获取该类及其父类所有的构造对象 public static List<Constructor<?>> getAllConstructor(Class<?> clazz){ List<Constructor<?>> list = new ArrayList<>(); for (Class<?> c = clazz;c != null;c = c.getSuperclass()) { Constructor<?>[] constructors = c.getDeclaredConstructors(); Collections.addAll(list, constructors); } return list; } //创建该类的对象 public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] values){ try { Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes); constructor.setAccessible(true); T t = constructor.newInstance(values); return t; } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } //获取该类及其父类所有的方法对象 public static List<Method> getAllMethod(Class<?> clazz){ List<Method> list = new ArrayList<>(); for (Class<?> c = clazz;c != null;c = c.getSuperclass()) { Method[] methods = c.getDeclaredMethods(); Collections.addAll(list, methods); } return list; } //获取指定的方法对象 public static Method getMethod(Class<?> clazz,String methodName,Class<?>... parameterTypes){ for(Class<?> c = clazz;c != null;c = c.getSuperclass() ){ try { Method method = c.getDeclaredMethod(methodName, parameterTypes); return method; } catch (NoSuchMethodException e) { } } return null; } //调用成员方法 public static Object invoke(Object obj,String methodName,Class<?>[] parameterTypes,Object[] values){ Method method = getMethod(obj.getClass(), methodName, parameterTypes); method.setAccessible(true); try { Object invoke = method.invoke(obj, values); return invoke; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } return null; } //调用静态方法 public static Object invoke(Class<?> clazz,String methodName,Class<?>[] parameterTypes,Object[] values){ Method method = getMethod(clazz, methodName, parameterTypes); method.setAccessible(true); try { Object invoke = method.invoke(null, values);//静态方法直接填null,因为不需要对象去调用 return invoke; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } return values; } } public class Student extends Person{ private String classId; private String id; public Student() { } public Student(String name, char sex, int age, String classId, String id) { super(name, sex, age); this.classId = classId; this.id = id; } public String getClassId() { return classId; } public void setClassId(String classId) { this.classId = classId; } public String getId() { return id; } public void setId(String id) { this.id = id; } // private String method01(String str){ // System.out.println("私有的方法 :" + str); // return "用良心做教育"; //} @Override public String toString() { return "Student [classId=" + classId + ", id=" + id + ", getName()=" + getName() + ", getSex()=" + getSex() + ", getAge()=" + getAge() + "]"; } public static void method02(){ System.out.println("静态的方法"); } } #### 9.反射机制 之 扩展属性的运用 #### import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Properties; public class Test01 { public static void main(String[] args) throws Exception { Properties p = new Properties(); p.load(Test01.class.getClassLoader().getResourceAsStream("classpath.properties")); String path = p.getProperty("path"); Class<?> clazz = Class.forName(path); //获取学生类中的name属性 Field field = ReflexUtil.getField(clazz, "name"); //获取属性参数值 int modifiers = field.getModifiers(); System.out.println("判断属性是否是私有化的:" + Modifier.isPrivate(modifiers)); System.out.println("判断属性是否是Protected的:" + Modifier.isProtected(modifiers)); System.out.println("判断属性是否是公有的:" + Modifier.isPublic(modifiers)); System.out.println("判断属性是否是静态的:" + Modifier.isStatic(modifiers)); System.out.println("判断属性是否是常量的:" + Modifier.isFinal(modifiers)); } } #### 10.反射机制 之 扩展方法的运用 #### import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Properties; public class Test02 { @SuppressWarnings("all") public static void main(String[] args) throws Exception { Properties p = new Properties(); p.load(Test02.class.getClassLoader().getResourceAsStream("classpath.properties")); String path = p.getProperty("path"); Class<?> clazz = Class.forName(path); //获取学生类中的method02 Method method = ReflexUtil.getMethod(clazz, "method02",null); //获取方法参数值 int modifiers = method.getModifiers(); System.out.println("判断方法是否是私有化的:" + Modifier.isPrivate(modifiers)); System.out.println("判断方法是否是Protected的:" + Modifier.isProtected(modifiers)); System.out.println("判断方法是否是公有的:" + Modifier.isPublic(modifiers)); System.out.println("判断方法是否是静态的:" + Modifier.isStatic(modifiers)); System.out.println("判断方法是否不可重写的:" + Modifier.isFinal(modifiers)); System.out.println("判断方法是否同步的:" + Modifier.isSynchronized(modifiers)); System.out.println("判断方法是否抽象的:" + Modifier.isAbstract(modifiers)); } } #### 11.反射案例之万能数组扩容/复制 #### import java.lang.reflect.Array; import java.util.Arrays; public class Test01 { public static void main(String[] args) { int[] is = { 1,2,3,4,5}; int[] copy1 = copy(is,10); System.out.println(Arrays.toString(copy1)); System.out.println("---------"); String[] names = { "后裔","狄仁杰","李元芳","孙尚香"}; String[] copy2 = copy(names,10); System.out.println(Arrays.toString(copy2)); } public static <T> T copy(T t,int newLength){ //获取数组的class对象 Class<? extends Object> clazz = t.getClass(); //获取数组元素类型的class对象 Class<?> elementClazz = clazz.getComponentType(); //创建数组 @SuppressWarnings("unchecked") T arr = (T) Array.newInstance(elementClazz, newLength); //遍历原数组 for (int i = 0; i < Array.getLength(t); i++) { //获取指定下标上的元素 Object element = Array.get(t, i); //将元素设置给新数组 Array.set(arr, i, element); } return arr; } } #### 12.反射案例 之 逻辑与业务分离的思想 #### * 业务场景:获取数据 * 分析: * 获取本地数据 – 代码 * 获取网络数据 – 代码 * 获取其他数据 – 代码 import java.util.List; import java.util.Scanner; public class Test01 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); printMenu(); int num = scan.nextInt(); DataSource dataSource = getDataSourceObj(num); dataSource.getDataSource(); scan.close(); } public static DataSource getDataSourceObj(int num){ List<String> classlist = DataContainer.classList; String classPath = classlist.get(num-1); try { Class<?> clazz = Class.forName(classPath); DataSource dataSource = (DataSource) clazz.newInstance(); return dataSource; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } private static void printMenu() { List<String> menulist = DataContainer.menuList; System.out.println("请选择获取数据的方式:"); for (String str : menulist) { System.out.println(str); } } } import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; public class DataContainer { public static final List<String> menuList; public static final List<String> classList; static{ //初始化菜单集合 menuList = new ArrayList<>(); Properties menuProperties = new Properties(); try { menuProperties.load(DataContainer.class.getClassLoader().getResourceAsStream("menuConfig.properties")); } catch (IOException e) { e.printStackTrace(); } String menu = menuProperties.getProperty("menu"); String[] menuSplit = menu.split(","); for (String str : menuSplit) { menuList.add(str); } //初始化类路径集合 classList = new ArrayList<>(); Properties classProperties = new Properties(); try { classProperties.load(DataContainer.class.getClassLoader().getResourceAsStream("classConfig.properties")); } catch (IOException e) { e.printStackTrace(); } String path = classProperties.getProperty("path"); String[] pathSplit = path.split(","); for (String str : pathSplit) { classList.add(str); } } } public abstract class DataSource { public abstract void getDataSource(); } public class LocalDataSource extends DataSource{ @Override public void getDataSource() { System.out.println("执行获取本地数据的代码..."); } } public class NetworkDataSource extends DataSource{ @Override public void getDataSource() { System.out.println("执行获取网络数据的代码..."); } } public class OtherDataSource extends DataSource{ @Override public void getDataSource() { System.out.println("执行获取其他数据的代码..."); } } #### 13.反射案例 之 获取注解信息 #### import java.lang.reflect.Field; public class Test01 { public static void main(String[] args) { Student stu = new Student("刘备", '男', 23); Class<? extends Student> clazz = stu.getClass(); //获取类上注解的信息 TableInfo tableInfoAnnotation = clazz.getAnnotation(TableInfo.class); String tableName = tableInfoAnnotation.value(); System.out.println(tableName); //获取属性上注解的信息 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { FieldInfo fieldInfoAnnotation = field.getAnnotation(FieldInfo.class); String name = fieldInfoAnnotation.name(); String type = fieldInfoAnnotation.type(); int length = fieldInfoAnnotation.length(); Object value = null; try { field.setAccessible(true); value = field.get(stu); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } System.out.println(name + " -- " + type + " -- " + length + " -- " + value); } //insert into s_student(s_name,s_sex,s_age) values("刘备","男",23) } } @TableInfo("s_student") public class Student { @FieldInfo(name="s_name",type="varchar",length=32) private String name; @FieldInfo(name="s_sex",type="varchar",length=32) private char sex; @FieldInfo(name="s_age",type="int",length=3) private int age; public Student() { } public Student(String name, char sex, int age) { this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]"; } } import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface TableInfo { String value(); } import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface FieldInfo { String name(); String type(); int length(); }
还没有评论,来说两句吧...