注解 :不仅人能看,而且程序也能看。
注解有检查和规范的作用。
(1、1.1 )
1、内置注解
(1、1.2 )
2、元注解
(1、1.3 )
package annotation; import java.lang.annotation.*; //测试元注解 @MyAnnotation public class Test01 { public void test(){ } } //定义一个注解 //Target 表示我们注解可以用在那些地方 @Target(value = {ElementType.ANNOTATION_TYPE,ElementType.TYPE}) //Retention 表示我们注解在什么地方还有效 @Retention(value = RetentionPolicy.RUNTIME) //表示是否将注解生成在JavaDOC文档 @Documented // 子类可以继承父类的注解 @Inherited @interface MyAnnotation{ }
3、自定义注解
(1、1.4 )
package annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //自定义注解 public class Test02 { //注解可以显示赋值,如果没有默认值,我们就必须给注解赋值 @MyAnnotation2(name = "hello word",schools = {"1,2,3,4"}) public void test2(){ } } @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation2{ //注解的参数 String name(); int age() default 0;//默认值 int id() default -1;//如果默认值为-1,代表不存在。 String [] schools(); }
1.2 反射机制
1、获得反射机制
(1、1.5 )
(1、1.6 )
package reflection; //什么叫反射 public class Test1 { public static void main(String[] args) throws ClassNotFoundException { //通过反射获取类的class对象 Class c1 = Class.forName("reflection.User"); System.out.println(c1); } } //一个类中只有属性称之为实体类。和数据库去映射。 //实体类 : entity pojo class User{ private String name; private int age; private int id; public User(){ } public User(String name,int age,int id){ this.name = name; this.age = age; this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", id=" + id + '}'; } }
2、得到class中几种方式
(1、1.7 )
(1、1.8 )
package reflection; //测试class类中方式有哪些 public class Test2 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println("这个人是"+person.name); //方式一 :通过对象获得 Class c1 = person.getClass(); //方式二 :通过forName 获得 Class c2 = Class.forName("reflection.Student"); //方式三 :通过类名.class获得 Class c3 = Student.class; //方式四 :基本内置属性的包装类都有一个Type属性 Class c4 = Integer.TYPE; System.out.println(c4); //获得父类的类型 Class c5 = c1.getSuperclass(); System.out.println(c5); } } class Person{ public String name; public Person() { } public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person{ public Student() { this.name = "学生"; } } class Teacher extends Person{ public Teacher() { this.name = "老师"; } }
3、所有class对象
(1、1.9 )
package reflection; import java.lang.annotation.ElementType; //所有类型的class对象 public class Test3 { public static void main(String[] args) { Class c1 = Object.class; //类 Class c2 = Comparable.class; //接口 Class c3 = String[].class; //一维数组 Class c4 = int [][].class; //二维数组 Class c5 = Override.class; //注解 Class c6 = ElementType.class; //枚举 Class c7 = Integer.class; //基本数据类型,int的包装类 Class c8 = void.class; //void Class c9 = Class.class; //class System.out.println(c1); System.out.println(c2); System.out.println(c3); System.out.println(c4); System.out.println(c5); System.out.println(c6); System.out.println(c7); System.out.println(c8); System.out.println(c9); int [] a = new int[10]; int [] b = new int[100]; //两个长度不一样的数组,但是他们都是同一个类型,都是int类型, // 他们底层的hashCode都一样 System.out.println(a.getClass().hashCode()); System.out.println(b.getClass().hashCode()); } }
4、类加载内存分析
(1、1.10 )
(1、1.11 )
(1、1.12 )
5、类初始化
(1、1.13 )
package reflection; //测试类什么时候初始化 public class Test4 { static { System.out.println("main类被加载"); } public static void main(String[] args) throws ClassNotFoundException { //1.主动引用 Son son = new Son(); //反射也会产生主动引用 Class.forName("reflection.Son"); //不会产生类的引用方法,子类不会初始化 System.out.println(Son.b); //不会加载类 Son [] array = new Son[10]; } } class Father{ static int b = 5; static { System.out.println("父类被加载"); } } class Son extends Father{ static { System.out.println("子类被加载"); m = 300; } static int m = 100; static final int M = 1; }
6、类加载器
(1、1.14 )
(1、1.15 )
package reflection; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test6 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //获得Class对象 Class c1 = Class.forName("reflection.User"); //构造一个对象 User user = (User) c1.newInstance();//本质上是调用无参构造器 System.out.println(user); //通过构造器创建对象 //Constructor Constructor = c1.getDeclaredConstructor(String.class, int.class, int.class); //User user2 = (User) Constructor.newInstance("你好", 1, 18); //System.out.println(user2); //通过反射调用方法 User user3 = (User) c1.newInstance(); //通过反射获取一个方法 Method setName = c1.getDeclaredMethod("setName", String.class); //invoke : 激活的意思 //(对象,对象的值) setName.invoke(user3,"你好"); System.out.println(user3.getName()); //通过反射创建属性 User user4 = (User) c1.newInstance(); Field name = c1.getDeclaredField("name"); //不能直接操作私有属性,User是私有的在Test一中,我们需要关闭程序安全监测。 name.setAccessible(true); name.set(user4,"你好2"); System.out.println(user4.getName()); } }
1.3 性能分析
package reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; //分析性能问题 public class Test7 { //普通调用方法 public static void test(){ User user = new User(); //开始时间 long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { user.getName(); } //结束时间 long endTime = System.currentTimeMillis(); System.out.println("普通调用方法"+(endTime-startTime)+"ms"); } //反射调用方式 public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.invoke(user,null); } long endTime = System.currentTimeMillis(); System.out.println("反射调用方法"+(endTime-startTime)+"ms"); } //反射调用方式 关闭监测 public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); getName.setAccessible(true); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.invoke(user,null); } long endTime = System.currentTimeMillis(); System.out.println("反射关闭调用方法"+(endTime-startTime)+"ms"); } public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { test2(); test(); test3(); } } 输出结果 : 反射调用方法2458ms 普通调用方法4ms 反射关闭调用方法1326ms
1.4 获取泛型信息
(1、1.16 )