• 中文
    • English
  • 注册
  • 查看作者
  • Java 注解与反射 基础

    注解与反射 基础什么是注解Annotation注解

    Annotation的作用:不是程序本身,可以对程序做出解释。可以被其他程序(比如 编译器等)读取

    annotation的格式: 注解是以 ”@注释名“ 再代码中存在的,还可以添加一写参数值,例如@SupperWarnings(value = “unchecked”)

    Annotation在哪可以使用? 可以在package,class,method,field等上面,相当于给他们添加额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问

    内置注解@Override 重写

    @Deprecated 不鼓励使用,但是可以使用

    @SuppreWarning 警告

    元注解元注解的作用是负责注解其他注解

    @Target

    @Retention

    @Documented

    @ Inherited

    package opp2;

    import java.lang.annotation.*;

    public class demo01 {public void test(){

    }

    //定义一个注解//Target 表示我们的注解可以用在上面地方@Target(value = {ElementType.METHOD, ElementType.TYPE})

    //Retention 表示我们的注解在上面地方有效//RUNTIME >CLASS >SOURCES@Retention(value = RetentionPolicy.RUNTIME)

    //Documented 表示释放将我们的注解生成在JavaDoc中@Documented

    //Inherited 子类可以继承父类的注解@Inherited@interface MyAnnotation{

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

    @interface用来声明一个注解,格式: public @interface 注解名{定义内容}其中的每一个方法实际上声明的是一个配置函数方法的名称就是参数的名称返回值类型就是参数的类型(返回值只能是基本类型,class,string,enum)可以通过default来声明参数默认值如果只有一个参数成员,一般参数名为value注解元素必须要有值,我们定义注解元素时,经常使用空字符串,0作为默认值package opp2;

    import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;

    public class demo02 {

    }

    @Target(value = {ElementType.METHOD, ElementType.TYPE})@Retention(value = RetentionPolicy.RUNTIME)@interface MyAnnotation2{//直接的参数:参数类型 +参数名()String name();String color() default “”;int age() default 0;int id() default -1;

    }

    @Target(value = {ElementType.METHOD, ElementType.TYPE})@Retention(value = RetentionPolicy.RUNTIME)@interface MyAnnotation3{String value();}反射java.Reflection

    时Java被视为动态语言的关键,反射机制允许程序在执行期借助Reflection api获得任何类的信息,并能直接操作任意对象的内部属性及方法。

    获得反射对象getClass()

    package opp2;

    /**

    • 什么是反射*/public class demo03 {public static void main(String[] args) throws ClassNotFoundException {Class c1 = Class.forName(“opp2.User”);Class c2 = Class.forName(“opp2.User”);Class c3 = Class.forName(“opp2.User”);System.out.println(c1);

    • }}

    //实体类class User{private String name;private int id;private int age;

    }得到class类的几种方式Java 注解与反射 基础插图

    package opp2;

    public class demo04 {public static void main(String[] args) throws ClassNotFoundException {Person person = new student();System.out.println(person.name);

    }

    class Person{String name;public Person(){}

    }class student extends Person{public student(){this.name = “学生”;}}

    class teacher extends Person{public teacher(String name) {this.name = “老师”;}}所有类型的Class对象class:外部类、成员(内部成员、外部成员),局部内部类,匿名内部类

    interface:接口

    [] :数组

    enum:枚举

    annotation:注解@interface

    primitive type:基本数据类型

    void

    package opp2;

    import javax.xml.bind.Element;

    public class demo {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 = Element.class; //枚举Class c7 = Integer.class; //基本数据类型Class c8 = void.class; //voidClass c9 = Class.class; //Class

    }类加载内存分析加载——>链接—->初始化

    package opp2;

    public class demo06 {public static void main(String[] args) {A a = new A();System.out.println(a.m);/*** 1.【加载】到内存,会产生一个类对应的Class对象* 2.【链接】,链接后, m = 0* 3.【初始化】:* (){* system.out.println(“A类的静态代码块初始化”);* m = 300;* m = 100;* }*/}}

    class A{static {System.out.println(“A类的静态代码块”);m = 300;}

    }分析类初始化类的主动引用(一定会发生初始化)类的被动引用(不会发生类的初始化)package opp2;

    public class demo07 {

    }

    class F{static int b = 2;static {System.out.println(“父类被加载”);}}

    class S extends F{static {System.out.println(“子类被加载”);m = 300;}static int m = 100;static final int M = 1; //常量}类加载器Java 注解与反射 基础插图1

    package opp2;

    public class demo08 {public static void main(String[] args) throws ClassNotFoundException {//获取系统类的加载器ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();System.out.println(systemClassLoader);//获取系统类加载器的父类加载器->扩展加载器ClassLoader parent = systemClassLoader.getParent();System.out.println(parent);

    }获取类的运行时结构通过反射获取运行时类的完整结构

    Field、Method、Constructor、Superclass、Interface、Annotation

    package opp2;

    import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;

    public class demo09 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {Class c1 = Class.forName(“opp2.User”);

    // for (Field field1 : field){// System.out.println(field1);// }//field = c1.getDeclaredFields();for (Field fields : field){ //找到全部属性System.out.println(fields);}

    }动态创建对象执行方法能做啥?

    步骤:

    通过Class类的getDeclaredConstructor(Class … parameterType)获取本类的指定形参类型的构造器向构造器的行参中传递一个对象素组进去,里面包含了构造器中所需的各个参数通过Constructor实例化对象package opp2;

    import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;

    public class demo10 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {

    }性能对比分析setAccessible:启动和禁用访问安全检查的开关。参数值为true则指反射的对象在使用时应该取消java语言访问检查

    提高反射效率。如果代码中必须使用反射,而该句代码需要频发的被调用,那么请设置为true使得原本无法访问的私有成员也可以访问参数值为false则指反射的对象在使用时对java语言进行访问检查

    package opp2;

    import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;

    public class demo11 {public static void test1(){User user = new User();long startTime = System.currentTimeMillis();for (int i = 0; i < 1000000000; i++) {user.getName();}long endTime = System.currentTimeMillis();System.out.println("普通方法执行10亿次 " + (endTime-startTime)+"ms");}

    }获取泛型信息Java采用泛型擦除的机制来引入泛型,Java中的泛型仅仅是给编辑器javac使用的,确保数据的安全性和免去强制类型转换问题,但是,一旦编译完成,所有和泛型有关的类型全部擦除

    为了通过反射操作这些类型,Java新增了ParameterizedType,GenericArrayType,TypeVariable和WindcardType几种类型来代表不能被归一到Class类中的类型但是又和原始类型齐名的类型

    ParameterizedType:表示一种参数化类型,不如CollectionGenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型TypeVariable:是各种类型变量的公共父接口WindcardType:代表一种通配符类型的公示package opp2;

    import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.List;import java.util.Map;

    /**

    • 通过反射回去泛型*/public class demo12 {public void test(Map map, Listlist){System.out.println(“test01”);}public Map test02(){System.out.println(“test02”);return null;}

    • public static void main(String[] args) throws NoSuchMethodException {Method method = demo12.class.getMethod(“test”, Map.class, List.class);Type[] genericParameterTypes = method.getGenericParameterTypes();for (Type ge : genericParameterTypes){System.out.println(“#” + ge);if (ge instanceof ParameterizedType){Type[] actualTypeArguments = ((ParameterizedType) ge).getActualTypeArguments();for (Type act : actualTypeArguments){System.out.println(act);}}}method = demo12.class.getMethod(“test02”, null);Type genericParameterType = method.getGenericReturnType();if (genericParameterType instanceof ParameterizedType){Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();for (Type act : actualTypeArguments){System.out.println(act);}}}}获取注解信息ORM 对象关系映射

    package opp2;

    import java.lang.annotation.*;import java.lang.reflect.Field;

    /**

    • 练习反射操作注解*/public class demo13 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {Class c1 = Class.forName(“opp2.Student2”);Annotation[] annotation = c1.getAnnotations();

    // Field name = c1.getDeclaredField(“name”);Field name = c1.getDeclaredField(“id”);Fk annotation1 = name.getAnnotation(Fk.class);System.out.println(annotation1.columnName());System.out.println(annotation1.Type());System.out.println(annotation1.length());

    }

    @TableM(“db_student”)class Student2{@Fk(columnName = “db_id”,Type = “int”, length = 10)private int id;@Fk(columnName = “db_age”,Type = “int”, length = 10)private int age;@Fk(columnName = “db_name”, Type = “varchar”, length = 3)private String name;public Student2(){

    }

    //类名的注解@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@interface TableM{String value();}

    //属性的注解@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@interface Fk{String columnName();String Type();int length();}

  • 0
  • 0
  • 0
  • 16
  • 请登录之后再进行评论

    登录
  • 任务
  • 实时动态
  • 发布
  • 单栏布局 侧栏位置: