本文主要是介绍Day26,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Day26
注解
什么是注解
java.annotation包Annotation是从JDK1.5开始引入的新技术,注解即可以对程序员解释又可以对程序解释
注解与注释的区别
注释:对程序员解释代码信息注解:对程序和程序员解释代码信息
注解的所用
- 不是程序本身,可以对程序作出解释(与注释(comment)类似)2. 可以被其他程序(编译器)读取
注解的格式
注解是以“@注释名”在代码中存在的,还可以添加一些参数例如:@SuppressWarnings(value=“unchecked”)
注解的应用
可以附加在package、class、method、field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制实现对这些数据的访问
知识点:内置注解
理解:Java给我们提供的注解
@Override - 重写父类方法的注解
@SuppressWarnings - 镇压警告的注解
@Deprecated - 已弃用的注解@Deprecatedpublic void method02(){}@SuppressWarnings("all")public void method01(){ArrayList list = new ArrayList();list.add(100);list.add(123.123);}@Overridepublic String toString() {return super.toString();}
元注解
元注解的作用:负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明
这些类型和它们所支持的类在java.lang.annotation包中可以找到
(@Target,@Retention,@Documented,@Inherited )
*@Target*:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
*@**Retention*:表示需要要在什么级别保存该注择信息,用于描述注解的生命周期
(SOURCE < CLASS < *RUNTIME*)
@Document:说明该注解将被包含在javadoc中
@lnherited:说明子类可以继承父类中的该注解
知识点:自定义注解
@interface用来声明一个注解,格式:public @interface注解名{定义内容}
其中的每一个方法实际上是声明了一个配置参数.
方法的名称就是参数的名称.
返回值类型就是参数的类型(返回值只能是基本类型、Class、String、enum)
可以通过default来声明参数的默认值
如果只有一个参数成员,一般参数名为value()
注解元素必須要有值,我们定义注解元素时,经常使用空字符串.0作为默认值
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotaction {}@MyAnnotactionpublic void method01() {}
@Target({TYPE,FIELD,CONSTRUCTOR,METHOD,PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotaction {String value(); } @MyAnnotaction("aaa")public class Test01 {/*** 知识点:自定义注解*/@MyAnnotaction("aaa")String str;@MyAnnotaction("aaa")public Test01() {}@MyAnnotaction(value = "aaa")public void method01() {}@MyAnnotaction("aaa")public void method02(@MyAnnotaction("aaa") int i) {} }
@Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotaction {String value() default "abc"; }public class Test01 {/*** 知识点:自定义注解*/@MyAnnotaction(value = "aaa")public void method01() {}@MyAnnotaction("aaa")public void method02() {}@MyAnnotaction()public void method03() {}@MyAnnotactionpublic void method04() {} }
@Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotaction {String[] value(); }public class Test01 {/*** 知识点:自定义注解*/@MyAnnotaction(value = "aaa")public void method01() {}@MyAnnotaction({"aaa","bbb","ccc"})public void method02() {}@MyAnnotaction(value={"aaa","bbb","ccc"})public void method03() {} }
@Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotaction {String[] name(); }public class Test01 {/*** 知识点:自定义注解*/@MyAnnotaction(name = "aaa")public void method01() {}@MyAnnotaction(name = {"aaa","bbb","ccc"})public void method02() {}}
@Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotaction {String name();String info() default "xxx"; }public class Test01 {/*** 知识点:自定义注解*/@MyAnnotaction(name = "aaa",info="xxx")public void method01() {}@MyAnnotaction(name = "aaa")public void method02() {} }
反射
反射机制
知识点:反射机制
前言:
使用到一个类,JVM会将该类的class文件加载到方法区(一次),
同时会在堆中创建一个该类的class对象,该类的class对象作为
该class文件的访问入口。class文件里有什么?
该类中所有的信息,都在class文件里
比如:类信息、属性信息、方法信息…理解:反射机制就是获取到class对象,通过class对象操作class文件里的任意内容
学习路线:概念获取class对象操作属性操作构造方法操作方法操作参数、返回值操作泛型操作数组案例
知识点:获取class对象
public static void main(String[] args) throws ClassNotFoundException {//方式一:直接通过类名调用Class<? extends Student> clazz1 = Student.class;//方式二:通过该类的对象的getClass()获取该类的class对象Student stu = new Student();Class<? extends Student> clazz2 = stu.getClass();//方式三:Class<?> clazz3 = Class.forName("com.qf.reflex01.Student");System.out.println(clazz1 == clazz2);//trueSystem.out.println(clazz1 == clazz3);//true}
知识点:获取class对象 + 配置文件
public class Test02 {/*** 知识点:获取class对象 + 配置文件*/public static void main(String[] args) throws ClassNotFoundException, IOException {//创建properties对象Properties p = new Properties();//加载配置文件p.load(Test02.class.getClassLoader().getResourceAsStream("BeanConfig.properties"));//获取属性值String className = p.getProperty("className");Class<?> clazz = Class.forName(className);System.out.println(clazz);} }
知识点:封装工具 + 配置文件 -> 获取class对象
public class Test03 {/*** 知识点:封装工具 + 配置文件 -> 获取class对象*/public static void main(String[] args) {Class<?> clazz = ReflexUtil.getClazz();System.out.println(clazz);} }/*** 反射工具类* @author 何老师**/ public final class ReflexUtil {//配置文件里类的全限定名private static String className;//初始化配置文件static{Properties p = new Properties();try {p.load(ReflexUtil.class.getClassLoader().getResourceAsStream("BeanConfig.properties"));} catch (IOException e) {e.printStackTrace();}className = p.getProperty("className");}private ReflexUtil() {}/*** 获取配置文件里配置的class对象* @return class对象*/public static Class<?> getClazz(){return getClazz(className);}/*** 获取指定的class对象* @param className 类的全限定名* @return class对象*/public static Class<?> getClazz(String className){try {Class<?> clazz = Class.forName(className);return clazz;} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}
操作属性
public class Test04 {/*** 知识点:操作属性*/public static void main(String[] args) {//获取class对象 // Class<?> clazz = ReflexUtil.getClazz();//获取本类及其父类公有的属性对象 // Field[] fields = clazz.getFields(); // for (Field field : fields){ // System.out.println(field); // }//获取本类所有的属性对象 // Field[] fields = clazz.getDeclaredFields(); // for (Field field : fields) { // System.out.println(field); // }//获取本类及其父类所有的属性对象 // for(Class<?> c = clazz;c != null;c = c.getSuperclass()){ // Field[] fields = c.getDeclaredFields(); // for (Field field : fields) { // System.out.println(field); // } // }//通过属性名获取本类及其父类公有的属性对象 // try { // Field field = clazz.getField("classId"); // System.out.println(field); // } catch (NoSuchFieldException e) { // e.printStackTrace(); // } catch (SecurityException e) { // e.printStackTrace(); // }//通过属性名获取本类指定的属性对象 // try { // Field field = clazz.getDeclaredField("classId"); // System.out.println(field); // } catch (NoSuchFieldException e) { // // TODO Auto-generated catch block // } catch (SecurityException e) { // e.printStackTrace(); // }//通过属性名获取本类及其父类指定的属性对象 // for(Class<?> c = clazz;c != null;c = c.getSuperclass()){ // try { // Field field = c.getDeclaredField("name"); // System.out.println(field); // // //获取属性修饰信息 // int modifiers = field.getModifiers(); // System.out.println("判断属性是否使用public修饰:" + Modifier.isPublic(modifiers));//false // System.out.println("判断属性是否使用protected修饰:" + Modifier.isProtected(modifiers));//false // System.out.println("判断属性是否使用private修饰:" + Modifier.isPrivate(modifiers));//true // System.out.println("判断属性是否使用static修饰:" + Modifier.isStatic(modifiers));//false // System.out.println("判断属性是否使用final修饰:" + Modifier.isFinal(modifiers));//false // System.out.println("判断属性是否使用transient修饰:" + Modifier.isTransient(modifiers));//false // System.out.println("判断属性是否使用volatile修饰:" + Modifier.isVolatile(modifiers));//false // // } catch (NoSuchFieldException e) {//不输出错误信息,子类找不到没关系,直接去找父类 // } catch (SecurityException e) { // } // }//封装工具类 -- 通过属性名获取本类及其父类指定的属性对象 // Field field = ReflexUtil.getField(clazz, "name"); // System.out.println(field);//操作属性 -- 获取、设置 // Student stu = new Student(); // Field nameField = ReflexUtil.getField(clazz, "name"); // // nameField.setAccessible(true);//设置操作权限 // try { // //设置stu对象里面的name属性为侯小康 // nameField.set(stu, "侯小康"); // } catch (IllegalArgumentException e) { // e.printStackTrace(); // } catch (IllegalAccessException e) { // e.printStackTrace(); // } // System.out.println(stu);//封装工具类 -- 操作属性 -- 获取、设置Student stu = new Student();ReflexUtil.setField(stu, "name", "侯小康");ReflexUtil.setField(stu, "sex", '男');ReflexUtil.setField(stu, "age", 23);ReflexUtil.setField(stu, "classId", "2402");ReflexUtil.setField(stu, "id", "001");System.out.println(stu);} }
ReflexUitl.java里添加:
/*** 获取属性对象* @param clazz class对象* @param name 属性名* @return 属性对象*/public static Field getField(Class<?> clazz,String name){for(Class<?> c = clazz;c != null;c = c.getSuperclass()){try {Field field = c.getDeclaredField(name);return field;} catch (NoSuchFieldException e) {} catch (SecurityException e) {}}return null;}/*** 设置属性* @param obj 目标对象* @param name 属性名* @param val 属性值*/public static void setField(Object obj,String name,Object val){Class<? extends Object> clazz = obj.getClass();Field field = getField(clazz, name);field.setAccessible(true);try {field.set(obj, val);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}
操作构造方法
创建对象
反射机制中传入的基本数据类型会自动装箱,而使用类方法获取构造器时参数为class对象数组,且里面的元素是包装类,所以要先设计一个参数类型处理的方法
/*** 参数类型处理器* @param parameterVals 参数数据的可变参数* @return 参数类型的数组*/private static Class<?>[] parameterValsHandle(Object... parameterVals){ArrayList<Class<?>> list = new ArrayList<>();for (Object object : parameterVals) {Class<? extends Object> parameterType = object.getClass();if(parameterType == Byte.class){parameterType = byte.class;} else if(parameterType == Short.class){parameterType = short.class;} else if(parameterType == Integer.class){parameterType = int.class;} else if(parameterType == Long.class){parameterType = long.class;} else if(parameterType == Float.class){parameterType = float.class;} else if(parameterType == Double.class){parameterType = double.class;} else if(parameterType == Character.class){parameterType = char.class;} else if(parameterType == Boolean.class){parameterType = boolean.class;} list.add(parameterType);}Class<?>[] parameterTypes = new Class[list.size()];list.toArray(parameterTypes);return parameterTypes;}
思路为通过获取的class对象创建构造器,再用构造器去创建对象。
public static <T> T newInstance(Class<T> clazz,Object...parameterVals){Class<?>[] parameterTypes = parameterValsHandle(parameterVals);try {Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);constructor.setAccessible(true);T t = constructor.newInstance(parameterVals);return t;} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}
public class Test05 {/*** 知识点:操作构造方法*/@SuppressWarnings("all")public static void main(String[] args) {//获取class对象Class<Student> clazz = (Class<Student>) ReflexUtil.getClazz();//获取本类公有的构造方法 // Constructor<?>[] constructors = clazz.getConstructors(); // for (Constructor<?> constructor : constructors) { // System.out.println(constructor); // }//获取本类所有的构造方法 // Constructor<?>[] constructors = clazz.getDeclaredConstructors(); // for (Constructor<?> constructor : constructors) { // System.out.println(constructor); // }//获取本类及其父类所有的构造方法 // for(Class<?> c = clazz;c != null;c = c.getSuperclass()){ // Constructor<?>[] constructors = c.getDeclaredConstructors(); // for (Constructor<?> constructor : constructors) { // System.out.println(constructor); // } // }//获取无参构造方法对象,利用无参构造方法对象创建该类的对象 // try { // //获取无参构造方法对象 // Constructor<?> constructor = clazz.getDeclaredConstructor(); // //利用无参构造方法对象创建该类的对象 // Student stu = (Student) constructor.newInstance(); // System.out.println(stu); // } 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(); // }//利用无参构造方法对象创建该类的对象 // try { // Student stu = (Student) clazz.newInstance(); // System.out.println(stu); // } catch (InstantiationException e) { // e.printStackTrace(); // } catch (IllegalAccessException e) { // e.printStackTrace(); // }//获取有参构造方法对象,利用有参构造方法对象创建该类的对象 // try { // //获取有参构造方法对象 // Constructor<?> constructor = clazz.getDeclaredConstructor(String.class,char.class,int.class,String.class,String.class); // //设置操作权限 // constructor.setAccessible(true); // //利用有参构造方法对象创建该类的对象 // Student stu = (Student) constructor.newInstance("侯小康",'男',23,"2402","001"); // System.out.println(stu); // } 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(); // }//封装工具类 -- 创建对象 // Student stu = ReflexUtil.newInstance(clazz); // System.out.println(stu);//封装工具类 -- 创建对象Student stu = ReflexUtil.newInstance(clazz, "侯小康",'男',23,"2402","001");System.out.println(stu);} }
操作方法、参数、返回值及泛型
知识点:操作方法
public class Test06 {/*** 知识点:操作方法*/@SuppressWarnings("all")public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {//获取class对象Class<Student> clazz = (Class<Student>) ReflexUtil.getClazz();//获取本类及其父类的公有方法对象 // Method[] methods = clazz.getMethods(); // for (Method method : methods) { // System.out.println(method); // }//获取本类的所有方法对象 // Method[] methods = clazz.getDeclaredMethods(); // for (Method method : methods) { // System.out.println(method); // }//获取本类及其父类所有方法对象 // for(Class<?> c = clazz;c != null;c = c.getSuperclass()){ // Method[] methods = c.getDeclaredMethods(); // for (Method method : methods) { // System.out.println(method); // } // }//通过方法名获取方法对象 // try { // Method method = clazz.getDeclaredMethod("setClassId", String.class); // method.setAccessible(true); // System.out.println(method); // // //获取方法修饰信息 // int modifiers = method.getModifiers(); // System.out.println("判断方法是否使用public修饰:" + Modifier.isPublic(modifiers));//true // System.out.println("判断方法是否使用protected修饰:" + Modifier.isProtected(modifiers));//false // System.out.println("判断方法是否使用private修饰:" + Modifier.isPrivate(modifiers));//false // System.out.println("判断方法是否使用static修饰:" + Modifier.isStatic(modifiers));//false // System.out.println("判断方法是否使用final修饰:" + Modifier.isFinal(modifiers));//false // System.out.println("判断方法是否使用abstract修饰:" + Modifier.isAbstract(modifiers));//false // System.out.println("判断方法是否使用synchronized修饰:" + Modifier.isSynchronized(modifiers));//false // // } catch (NoSuchMethodException e) { // e.printStackTrace(); // } catch (SecurityException e) { // e.printStackTrace(); // }//调用成员方法 // Student stu = ReflexUtil.newInstance(clazz, "侯小康",'男',23,"2402","001"); // Method getClassIdMethod = clazz.getDeclaredMethod("getClassId"); // getClassIdMethod.setAccessible(true); // Object getClassIdMethodReturnVal = getClassIdMethod.invoke(stu); // System.out.println(getClassIdMethodReturnVal);//2402 // // Method setClassIdMethod = clazz.getDeclaredMethod("setClassId", String.class); // setClassIdMethod.setAccessible(true); // Object setClassIdMethodReturnVal = setClassIdMethod.invoke(stu, "2403"); // System.out.println(setClassIdMethodReturnVal);//null // // System.out.println(stu);//调用静态 // Method method = clazz.getDeclaredMethod("method", String.class,int.class); // method.setAccessible(true); // Object methodReturnVal = method.invoke(null, "abc",888); // System.out.println(methodReturnVal);//封装工具类 -- 调用成员方法 // Student stu = ReflexUtil.newInstance(clazz, "侯小康",'男',23,"2402","001"); // Object getClassIdMethodReturnVal = ReflexUtil.invoke(stu, "getClassId"); // System.out.println(getClassIdMethodReturnVal);//2402 // // Object setClassIdMethodReturnVal = ReflexUtil.invoke(stu, "setClassId", "2403"); // System.out.println(setClassIdMethodReturnVal);//null // System.out.println(stu);//封装工具类 -- 调用静态Object methodReturnVal = ReflexUtil.invoke(clazz, "method", "abc",888);System.out.println(methodReturnVal);} }
工具类相关方法创建:
/*** 获取方法对象* @param clazz class对象* @param name 方法名* @param parameterTypes 方法参数类型数组* @return 方法对象*/public static Method getMethod(Class<?> clazz,String name,Class<?>... parameterTypes){for(Class<?> c = clazz;c != null;c = c.getSuperclass()){try {Method method = c.getDeclaredMethod(name, parameterTypes);return method;} catch (NoSuchMethodException e) {} catch (SecurityException e) {}}return null;}/*** 调用静态方法* @param clazz class对象* @param name 方法名* @param parameterVals 参数数组* @return 返回值*/public static Object invoke(Class<?> clazz,String name,Object... parameterVals){Class<?>[] parameterTypes = parameterValsHandle(parameterVals);Method method = getMethod(clazz, name, parameterTypes);try {Object returnVal = method.invoke(null, parameterVals);return returnVal;} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return null;}/*** 调用成员方法* @param obj 对象* @param name 方法名* @param parameterVals 方法参数数组* @return 返回值*/public static Object invoke(Object obj,String name,Object... parameterVals){Class<? extends Object> clazz = obj.getClass();Class<?>[] parameterTypes = parameterValsHandle(parameterVals);Method method = getMethod(clazz, name, parameterTypes);try {Object returnVal = method.invoke(obj, parameterVals);return returnVal;} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return null;}
知识点:操作方法的参数和返回值
public class Test07 {/*** 知识点:操作方法的参数和返回值*/@SuppressWarnings("all")public static void main(String[] args) {//获取class对象Class<Student> clazz = (Class<Student>) ReflexUtil.getClazz();Method method = ReflexUtil.getMethod(clazz, "method", String.class,int.class);//获取参数信息 -----------------------------------------------------------------------//获取参数列表的类型 // Class<?>[] parameterTypes = method.getParameterTypes(); // for (Class<?> c : parameterTypes) { // System.out.println(c); // }//获取参数对象数组 // Parameter[] parameters = method.getParameters(); // for (Parameter parameter : parameters) { // // Class<?> type = parameter.getType();//参数类型 // String name = parameter.getName();//参数名(注意:参数名不会随着编译而编译到class文件里) // System.out.println(type + " -- " + name); // }//获取参数个数 // int parameterCount = method.getParameterCount(); // System.out.println("获取参数个数:" + parameterCount);//2//获取返回值信息 -----------------------------------------------------------------------Class<?> returnType = method.getReturnType();System.out.println(returnType);//class java.lang.StringType genericReturnType = method.getGenericReturnType();System.out.println(genericReturnType);//class java.lang.String} }
知识点:操作泛型
public class Test08 {/*** 知识点:操作泛型*/public static void main(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException { // Class<Student> clazz = Student.class;Class<?> clazz = ReflexUtil.getClazz("Student");//获取属性上的泛型类型Field mapField = clazz.getDeclaredField("map");Type mapFieldGenericType = mapField.getGenericType();//获取属性类型ParameterizedType mapFieldPT = (ParameterizedType) mapFieldGenericType;//强转为子接口的类型Type[] actualTypeArguments = mapFieldPT.getActualTypeArguments();//获取泛型类型数组for (Type type : actualTypeArguments) {System.out.println(type);}//获取参数上的泛型类型Method method = clazz.getDeclaredMethod("method", ArrayList.class,ConcurrentHashMap.class);Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {Type type = parameter.getParameterizedType();ParameterizedType pt = (ParameterizedType) type;Type[] ata = pt.getActualTypeArguments();for (Type t : ata) {System.out.println(t);}}//获取返回值上的泛型类型Type genericReturnType = method.getGenericReturnType();ParameterizedType pt = (ParameterizedType) genericReturnType;Type[] actualTypeArguments2 = pt.getActualTypeArguments();for (Type type : actualTypeArguments2) {System.out.println(type);}} }
操作数组
知识点:操作数组
理解:Array类是Java提供的反射数组类
public static void main(String[] args) {//创建数组int[] arr = (int[]) Array.newInstance(int.class, 10);//获取长度System.out.println("获取长度:" + Array.getLength(arr));//10//循环遍历 - 设置数据for (int i = 0; i < Array.getLength(arr); i++) {Array.set(arr, i, i+1);//设置数据}//循环遍历 - 获取数据for (int i = 0; i < Array.getLength(arr); i++) {Object element = Array.get(arr, i);System.out.println(element);}}
这篇关于Day26的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!