java中的注解和反射
1什么是注解
(1)定义:Annotation是从Jdk5.0开始后才引入的,不是程序本身,可以对程序作出解释。可以被其他程序读取
(2)注解的使用:可以在package,class,method,field上面使用,相当于可以获得辅助的功能
2java中常用的内置注解
public class testAnnoaction extends Object { //重写的注解 @Override public String toString() { return super.toString(); } //加了这个注解,表示这个方法不推荐使用 @Deprecated public void test(){ } //镇压警告的功能,加上这个注解,可以将镇压警告进行消除 @SuppressWarnings("all") public void testTwo(){ ArrayList<Object> list = new ArrayList<>(); } }
3元注解
(1)作用:负责注解其他注解,java中定义了4个标准的注解,他们给用来给其他的注解annotation做说明
(2)@Target,@Rtention,@Documented,@inherited
(3)Target:用来描述注解的使用范围。Retention:表示在什么级别保存该注解的信息,用于描述注解的生命周期(SOURCE<CLASS<RUNTIME)。Documented:说明注解将被包含在doc中。inherited:说明子类可以继承父类的注解
(4)测试元注解
public class TestOther { @Myannotation public void method(){ } } //定义注解可以使用在方法上面 Target:表示注解可以用在哪些地方 @Target(value = ElementType.METHOD) //定义注解表示在什么阶段有效 RetentionPolicy:RUNTIME>CLASS>SOURCE @Retention(value = RetentionPolicy.RUNTIME) //表示是否将我们的注解生成在javaDoc中 @Documented //表示子类可以继承父类的注解 @Inherited @interface Myannotation{ }
4自定义注解
public class SelfAnnotation { /* * 1:注解可以显示赋值,如果没有默认值,我们必须要给赋值 * 2:注解的参数顺序没有关系 */ @MySelfAnnotation() @MySelfOtherAnnotation("value") public void testMethod(){ } } //表示注解可以在方法和类上面定义 @Target({ElementType.METHOD,ElementType.TYPE}) //表示注解在运行时有效 @Retention(RetentionPolicy.RUNTIME) @interface MySelfAnnotation{ //定义注解的参数:参数类型+参数名() String name() default ""; int age() default 0; int id() default -1; String[] schools() default{"重庆大学,清华大学"}; } //表示注解可以在方法和类上面定义 @Target({ElementType.METHOD,ElementType.TYPE}) //表示注解在运行时有效 @Retention(RetentionPolicy.RUNTIME) @interface MySelfOtherAnnotation{ //如果注解中只有一个值,在使用注解的时候,参数可以不加名称 String value(); }
java中的反射(将java不是动态语言可以变成动态语言,但是不安全)
1认识动态语言和静态语言
(1)动态语言:在运行的时候可以改变其结构的语言
(2)静态语言:与动态语言相比,运行时结构不可变的
2Reflection(缺点:极大地消耗性能)
(1)反射是java被视为动态语言的关键,反射机制可以允许程序在执行期间借助ReflectionApi获得类中的任何信息
(2)反射的原理1比较

(3)获得反射的对象
public static void main(String[] args) throws ClassNotFoundException { //通过反射获取类的class对象,一个类被加载后,整个类的结构都会在class中 Class aClass = Class.forName("reflection.User"); System.out.println(aClass); }
(4)获取class对象的几种方式
//1:通过对象获得 Class<? extends Person> c1 = person.getClass(); //2:用forName获得 Class<?> c2 = Class.forName("reflection.Student"); //3:通过类名获得(比较高效的使用) Class<Student> c3 = Student.class; System.out.println(c1.hashCode());//21685669 System.out.println(c2.hashCode());//21685669 System.out.println(c3.hashCode());//21685669 //4:基本内置类型的包装类都有一个type属性(不常用) Class<Integer> c4 = Integer.TYPE; //获取父类的类型 Class<?> superclass = c1.getSuperclass();
(5)哪些类有自己的class对象

(6)获取类的运行时的一些结构
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class aClass = Class.forName("annotation.User"); //获取类的名字 String className = aClass.getName(); System.out.println(className); System.out.println("================================="); //获得类的属性 Field[] fields = aClass.getFields();//只能找到public的属性 Field name = aClass.getDeclaredField("name"); Field[] declaredFields = aClass.getDeclaredFields();//获取全部属性包括私有的 for (Field declaredField : declaredFields) { System.out.println(declaredField); } System.out.println("==================================="); //获取类的方法 Method[] methods = aClass.getMethods();//获取本类和父类的所有方法 for (Method method : methods) { System.out.println("正常的"+method); } Method[] declaredMethods = aClass.getDeclaredMethods();//获取本类的所有方法(包括private) for (Field field : declaredFields) { System.out.println("declare"+field); } //获取指定的方法 Method getName = aClass.getMethod("getName", null); System.out.println(getName); }
(7)运用获取的属性和方法执行
public class User { private String name; public String userName; public void getName(String params,String params1) { System.out.println("我执行了这个方法"+params+","+params1); } public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { Class<?> aClass = Class.forName("annotation.User"); //通过反射创建一个对象 User user =(User) aClass.newInstance(); //通过反射调用普通方法 Method getName = aClass.getDeclaredMethod("getName", String.class,String.class); //调用了getName这个方法(第一个参数是对象,第二个参数是方法中的参数) getName.invoke(user,"xst","xxx"); } }
(8)比较普通创建对象和用反射创建对象的性能问题
public class TestTime{ public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Student.test01(); Student.test02(); Student.test03(); } } class Student{ public String name; public void getName(){ } //通过对象的方法调用 public static void test01(){ Student student = new Student(); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { student.getName(); } long endTime = System.currentTimeMillis(); System.out.println(endTime-startTime+"毫秒");//2毫秒 } //反射的方式调用 public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { //通过对象的方法调用 Student student = new Student(); Class<? extends Student> aClass = student.getClass(); Method getName = aClass.getDeclaredMethod("getName"); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.invoke(student,null); } long endTime = System.currentTimeMillis(); System.out.println(endTime-startTime+"毫秒");//909毫秒 } //关闭检测(可以提高速度 但是不安全 关闭检测后可以访问到私有的方法) public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { //通过对象的方法调用 Student student = new Student(); Class<? extends Student> aClass = student.getClass(); Method getName = aClass.getDeclaredMethod("getName"); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.setAccessible(true); getName.invoke(student,null); // student.getName(); } long endTime = System.currentTimeMillis(); System.out.println(endTime-startTime+"毫秒");//493毫秒 } }
浙公网安备 33010602011771号