• JAVA高级特性反射和注解


     反射: 

    反射, 主要是指通过类加载, 动态的访问, 检测和修改类本身状态或行为的一种能力, 并能根据自身行为的状态和结果, 调整或修改应用所描述行为的状态和相关的语义。
     
    反射操作核心的概念“一切的操作都将使用Object完成, 类、 数组的引用都可以使用Object进行接收”
     
     实例化类对象的方式。 
     1。 Class<?> c1 = Class . for Name( " 完整的类路径")  常用
     2。 Class<?>c2 =类名.class
     3。 Class<?>c3 =new 类名( ).getClass( )
     
    Class 类常用操作
     1 getSimpleName()获取类名
     2 getName()获取完整的“包,类”名称;
     3 Class  类的使用   
     4 无参构造实例化对象
     5 public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
     6 IllegalAccessException {
     7 //通过类路径获取类Class对象
     8 Class<?> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");
     9 //调用newInstance()方法, 调用无参构造创建类对象
    10 Person person = (Person) clazz.newInstance();
    11 //操作对象
    12 person.setAge(12);
    13 person.setName("张三");
    14 System.out.println(person);
    15 }
    16   有参构造实例化对象
    17 public static void main(String[] args) throws ClassNotFoundException,
    18 InstantiationException, IllegalAccessException,
    19 IllegalArgumentException, InvocationTargetException {
    20 //获取类的Class对象
    21 Class<?> clazz =clazz.forName("com.project.enmutestdemo.fanshe.Person");
    22 //通过参数类型获取类的具体的某一个构造器
    23 Constructor<?> c = clazz.getConstructor(String.class,int.class);
    24 Person person = null;
    25 // 传入实参, 通过构造器创建类对象
    26 person = (Person) c.newInstance("张三", 20);
    27 System.out.println(person);
    Constructor 构造器类 常用的方法 
    Field 类常用方法 
     1 getmodified  获取访问修饰符(public private 。。。)
     2 取得类中属性
     3 public static void main(String[] args) throws ClassNotFoundException {
     4 Class<?> clazz = null;
     5 //通过类路径获取类Class对象
     6 clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");
     7 //取得本类的属性
     8 Field[] f = clazz.getDeclaredFields();
     9 //循环操作类的属性
    10 for(int i = 0; i < f.length; i++){
    11 //取得该属性的类型
    12 Class<?> t = f[i].getType();
    13 //取得该属性的修饰符数字
    14 int mo = f[i].getModifiers();
    15 //通过修饰符数字取得属性的修饰符
    16 String priv = Modifier.toString(mo);
    17 System.out.print("本类属性: ");
    18 System.out.print(“ 修饰符为: ”+priv+" ");
    19 System.out.print(“类型为: ”+t.getName()+" ");
    20 System.out.print(“名称为: ”+f[i].getName()+”
    ”);
    21  
    22  
    23 通过反射 操作属性  
    24 //获取类的Class对象
    25 Class<?> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");
    26 //调用无参构造器创建类对象
    27 Object obj = clazz.newInstance();
    28 //通过属性名称获取属性的Field对象
    29 Field nameFiled = clazz.getDeclaredField("name");
    30 //通过set方法对对象的属性进行赋值
    31 nameFiled.set(obj, "张三");
    32 //通过get方法获取对象的属性值
    33 System.out.println(" 姓名: "+nameFiled.get(obj));
    34  
    35 操作类中的属性
    36 //获取类的Class对象
    37 Class<?> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");
    38 //调用无参构造器创建类对象
    39 Person obj = clazz.newInstance();
    40 //通过属性名称获取属性的Field对象
    41 Field nameFiled = clazz.getDeclaredField("name");
    42 //设置该属性的访问权限为可访问
    43 nameFiled.setAccessible(true);
    44 //通过set方法对对象的属性进行赋值
    45 nameFiled.set(obj, "张三");
    46 //通过get方法获取对象的属性值
    47 System.out.println(" 姓名: "+nameFiled.get(obj));
     
    Method 类常用方法
     1 取得类的全部方法
     2 //获取类的Class对象
     3 Class<?> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");
     4 Method[] method = clazz.getDeclaredMethods();//获取本类所有方法
     5 for(int i = 0; i < method.length;i++){//循环操作方法
     6 Class<?> r = method[i].getReturnType();//获取方法的返回值类型
     7 Class<?> p[] =method[i].getParameterTypes();//获取方法的参数类型
     8 int xx = method[i].getModifiers();//获取方法的修饰符数字
     9 System.out.print(Modifier.toString(xx)+" ");//获取修饰符
    10 System.out.print(r.getSimpleName()+" ");//获取方法返回值类型名称;
    11 System.out.print(method[i].getName());//获取方法名称
    12 System.out.print("(");
    13 for(int x = 0; x < p.length;x++){//循环操作参数类型
    14 System.out.print(p[x].getSimpleName() +" "+ "arg"+x);//输出参数
    15 if(x < p.length -1){//判断是否输出“ , ”
    16 System.out.print(",");//输出“ , ”
    17 }
    18 }S
    19 ystem.out.println();//换行
    20 }
    21   调用类中的方法
    22 public static void main(String[] args) throws ClassNotFoundException,
    23 NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
    24 InvocationTargetException, InstantiationException {
    25 //获取类的Class对象
    26 Class<?> clazz = Class.forName("com.project.enmutestdemo.fanshe.Person");
    27 //通过方法名称获取无参Method对象
    28 Method me = clazz.getMethod("speak");
    29 //调用无参构造器创建类对象
    30 Object obj = clazz.newInstance()
    31 me.invoke(obj);
    32  
    33  
    利用反射,在控制台输出以下信息:
    public class UserPo{
    private int id;
    private String userName;
    private String userPass;
    }
     
     
     

    注解: 

     给程序 看的注释,  称为 注解(Annotation)    是代码里的特殊标记,可以在编译,类加载,运行时被读取,并执行相应的处理。 通过使用注解,可以在不改变原有的逻辑的情况下,在源文件嵌入一些补充的信息。
     Annotation  提供为程序元素 (包,类,构造器,方法,成员变量,参数,局部变量)设置 元数据的方法 , 它不能运行,只有成员变量,没有方法,跟修饰符一样地位
      
     基本 Annotation :
    @Override 限定重写父类方法,如果存在,则正确,反之 ,报错
    @Deprecated 表示某个程序或元素 已过时。
    @SuppressWaring:抑制编译器警告;
    @SafeVarargs:是JDK7专门为抑制“堆污染”警告提供的;
     
    自定义 注解 
    定义新的Annotation 类型使用@interface 关键字,例如
    Public  @interface Table{  
    }
     
    使用 Annotation   一般会放在另一行,并且放在修饰符之前,如
    @Table  
    public class Myclass{ 
    。。。。
    }
     成员变量声明 
    1  无形参的方法
      public @interface MyTag { 
             string name();
               int age ();
    }
    2   指定默认值  在指定成员变量时,使用default 关键字  
     public @interface MyTag{ 
      string name ()default “ 张三” ;
     int age ()  default 18;
    }
     
    成员变量的使用方式 
    1  无形参方法声明时
     public class AnnonationTest{
      @MyTag ( name = "张三",age=30)
    public void info(){
    ...
    }
    }
    2  默认值声明变量时 
     public class AnnonationTest{
      @MyTag 
    public void info(){
    }
    }
     
    Annoation 分类  
      根据 Annotation 是否包含成员变量, 我们把其分为两类
    1  没有成员变量的: 标记Annotation  仅用自身的存在与否提供信息 如重写
    2 包含成员变量的: 元数据 Annotation 
     
     
    元注解 (注解的注解)
     @Retention  : 用于指定 Annotation 可以保留多长时间
    @Target :  指定 Annotation 用于修饰那些元素
    @Documented: 用于被修饰的Annotation类将被javadoc工具提取成文档,
    默认情况下,javadoc是不包括注解的。
    @Inherited:指定Annotation具有继承性;
     
    @Retention(RetentionPolicy.RUNTIME)//元注解
    @Target(ElementType.TYPE)//元注解   都是修饰下面的Table 自定义注解的注解
    public @interface Table { // 自定义注解
            String name(); 
    }
    @Column(name = "name")
        String name;
        @Column(name = "age")
        int age; 
     注解同public 地位一样,同属性绑在一起,可以通过反射Field(属性)操作注解 
     
    @Retention
     包含一个名为value 的成员变量 , 是RetentionPolicy枚举类型 值如下 
    RetentionPolicy.SOURCE:Annotation只保留在源代码中,编译器编译时,
    直接丢弃这种Annotation;
    RetentionPolicy.RUNTIME:编译器把Annotation记录在class文件中。当运行java程序时,JVM会保留该Annotation,程序可以通过反射获取该Annotation的信息;
    RetentionPolicy.CLASS:编译器把Annotation记录在class文件中。当运行
    java程序时,JVM中不再保留该Annotation;
     
    @Target
    包含一个名为“value”的成员变量, 该value成员变量类
    型为ElementType[],ElementType为枚举类型, 其值为:
    ElementType.TYPE:能修饰类、接口或枚举类型;
    ElementType.FIELD:能修饰成员变量;
    ElementType.METHOD:能修饰方法;
    ElementType.PARAMETER:能修饰参数;
    ElementType.CONSTRUCTOR:能修饰构造器;
    ElementType.ANNOTATION_TYPE:能修饰注解;
    ElementType.LOCAL_VARIABLE:可用于局部变量上
    ElementType.PACKAGE:用于记录java文件的package信息
     
    提取Annotation 信息
    JDK主要提供两个类, 来完成Annotation的提取:
    java.lang.annotation.Annotation接口:所有 annotation 类型都要扩展的公共接口;
    java.lang.reflect.AnnotatedElement接口:该接口允许反射性地读取注解。
     
    java.lang.reflect.AnnotatedElement接口
    isAnnotationPresent(Class<? extends Annotation> annotationClass):判断该程序元素上是否存在指定类型的注解,如果存在则返回true,否则返回false;
    getAnnotation(Class<T> annotationClass):返回该程序元素上存在的指定
    类型的注解,如果该类型的注解不存在,则返回null;
    Annotation[] getAnnotations():返回该程序元素上存在的所有注解;
    Annotation[] getDeclaredAnnotations() :返回直接存在于此元素上的所有注解。
     
    通过反射取得Annotation
     
    取得指定的Annotation ; 
     
  • 相关阅读:
    git使用记录
    【转】话说我打算一天学完object c语法,系列1--------来自书Objective-c程序设计
    【转】看源代码那些事
    中英文对照 —— 数学定律定理(公式及其描述)
    CUDA+OpenGL混合编程
    简明欧洲史
    简明欧洲史
    CUDA一维纹理内存
    CUDA中的常量内存__constant__
    CUDA线程协作之共享存储器“__shared__”&&“__syncthreads()”
  • 原文地址:https://www.cnblogs.com/thelovelybugfly/p/10822065.html
Copyright © 2020-2023  润新知