> 文档中心 > Java基础-注解 & 反射(十一)

Java基础-注解 & 反射(十一)

文章目录

  • 一、注解入门
    • 1.注解概述
    • 2.注解分类
      • 2.1 内置注解
      • 2.2 自定义注解
      • 2.3 元注解
  • 二、反射
    • 2.1 Java反射机制概述
      • 2.1.1 反射机制与应用
      • 2.1.2 反射的优点和缺点
      • 2.1.3 反射相关的主要API
    • 2.2 理解Class类并获取Class实例
      • 2.2.1 Class类的常用方法
      • 2.2.2 获取Class类的实例
      • 2.2.3 哪些类型可以有Class对象
      • 2.2.4 Java内存分析
    • 2.3 创建运行时类的对象
      • 2.3.1 了解类的加载过程
      • 2.3.2 类的加载与ClassLoader的理解
      • 2.3.3 什么时候会出现类初始化?
    • 2.4 类的加载与ClassLoader
      • 2.4.1 类加载器的作用
    • 2.5 获取运行时类的完成结构
    • 2.6有了Class对象能做什么呢?
    • 2.7 调用运行时类的指定结构
      • 2.7.1 调用指定的方法
    • 2.8 反射操作泛型(了解)
    • 2.9 反射操作注解

一、注解入门

1.注解概述

Java基础-注解 & 反射(十一)

/ * @author Daniel  * 注解概述 */public class ZhuJieDaniel extends Object{    //Override  重写的注解    @Override    public String toString() { return super.toString ();    }}

2.注解分类

2.1 内置注解

Java基础-注解 & 反射(十一)

/ * @author Daniel * 注解概述 */@SuppressWarnings ( "all" )//镇压警告注解  有此注解public不会出现底纹颜色public class ZhuJieDaniel extends Object{    //Override  重写的注解    @Override    public String toString() { return super.toString ();    }    @Deprecated //不鼓励程序员使用,但是可以使用,或者有更好的方式    public static void test1(){ System.out.println ("Deprecated");    } public static void test2(){ System.out.println ("SuppressWarnings");    }    public static void main(String[] args) { test1 ();// test2 ();    }}

运行结果为:
Java基础-注解 & 反射(十一)

2.2 自定义注解

Java基础-注解 & 反射(十一)

/ * @author Daniel  * 自定义注解 */public class ZiDingYiAnnonotion {    //注解可以显示赋值,如果没有默认值,我们就必须给注解赋值    @MyAnnotation1 ( name = "Daniel",age=18)    public void test1(){    }    @MyAnnotation2 ( "欢迎来到CSDN" )    public void test2(){    }}@interface  MyAnnotation1{    //注解的参数:参数类型 + 参数名();    String name() default "";    int age() ;    int id() default -1;//如果默认值为-1,则判定为不存在    String [] school() default ("深圳市福田区");}@interface  MyAnnotation2{     String value();}

2.3 元注解

Java基础-注解 & 反射(十一)

** * @author Daniel * 元注解 */@MyAnnotion//public class YuanZhuJie{    @MyAnnotion//方法注解    public void test(){    }}//@Retention ( value = RetentionPolicy.CLASS)//Retention 表示我们的注解在哪些地方还有效@Retention ( value = RetentionPolicy.RUNTIME)  //点击注解—>看源码//Target 表示我们的注解可以用在哪些地方@Target ( value = {ElementType.TYPE,ElementType.METHOD})//类注解和方法注解 TYPE 类注解  METHOD 方法注解@Documented   //表示是否将我们的注解生成在Javadoc中@Inherited//子类可以继承父类的注解@interface MyAnnotion{}

二、反射

Java基础-注解 & 反射(十一)

2.1 Java反射机制概述

1、java反射:在程序运行过程中,可以对任意一个类型进行任意的操作。例如:加载任意类型、调用类型的任意方法、获取任意的成员变量、构造方法,可以创建该类型的对象。
2、对于任意一个对象,都能调用这个对象的任意一个方法【不知道要使用什么类型】
3、如果要获取一个类型的各种内容,首先要获取这个类的字节码对象
4、解剖这个类型,获取类中的成员,需要使用Class类型中定义的方法
5、这种【动态】获取信息以及【动态】访问成员的这种方式,称为:反射
反射的举例:
房屋设计图纸---->实体房屋,反射:有了房屋,获取设计图纸
汽车设计图纸---->实体汽车,反射:有了汽车,获取设计图纸
无论是房屋设计图纸,还是汽车的设计图纸,都是图纸:抽取一个图纸类型
Java基础-注解 & 反射(十一)

/ * @author Daniel * 反射 */public class FanSheDaniel extends  Object{    //什么是反射    public static void main(String[] args) throws Exception { //通过反射获取类的Class对象 Class c1 = Class.forName ( "cn.Person" ); Class c2 = Class.forName ( "cn.Person" ); Class c3 = Class.forName ( "cn.Person" ); Class c4 = Class.forName ( "cn.Person" ); System.out.println ( c1 ); //一个类在内存中只有一个class对象 //一个类被加载后,类的整个结构都会被封装在Class对象中 System.out.println ( c1.hashCode () ); System.out.println ( c2.hashCode () ); System.out.println ( c3.hashCode () ); System.out.println ( c4.hashCode () );    }}//实体类:pojo,entityclass Person{    private String name;    private int age;    private int id;    public Person() {    }    public Person(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 "Person{" +  "name='" + name + '\'' +  ", age=" + age +  ", id=" + id +  '}';    }}

运行结果为:
Java基础-注解 & 反射(十一)

2.1.1 反射机制与应用

Java基础-注解 & 反射(十一)

2.1.2 反射的优点和缺点

Java基础-注解 & 反射(十一)

2.1.3 反射相关的主要API

Java基础-注解 & 反射(十一)
Java基础-注解 & 反射(十一)

2.2 理解Class类并获取Class实例

2.2.1 Class类的常用方法

Java基础-注解 & 反射(十一)

2.2.2 获取Class类的实例

Java基础-注解 & 反射(十一)

/ * @author Daniel  * 获取对象的方式 */public class FanSheDemo1 {    public static void main(String[] args) throws ClassNotFoundException { Person1 person1 = new Student(); System.out.println ("我是"+person1.name); //方式一:通过对象获得 Class c1 = person1.getClass (); System.out.println ( c1 ); //方式二:forname获得 Class  c2 = Class.forName ( "cn.Student" ); System.out.println (c2); //方式三:通过类名.class获得 Class<Student> c4 = Student.class; System.out.println ( c4 ); //方式四:基本内置类型的包装都有一个type属性 Class<Integer> c5 = Integer.TYPE; System.out.println (c5); //获得父类类型 Class c6 = c1.getSuperclass (); System.out.println (c6);    }}class Person1{    public String name;    public Person1() {    }    public Person1(String name) { this.name = name;    }    public String getName() { return name;    }    public void setName(String name) { this.name = name;    }    @Override    public String toString() { return "Person1{" +  "name='" + name + '\'' +  '}';    }}class Teacher extends Person1{    public Teacher(String name) { super ( "老师" );    }}class Student extends Person1{    public Student() {    }    public Student(String name) { super ( "学生" );    }}

运行结果为:
Java基础-注解 & 反射(十一)

2.2.3 哪些类型可以有Class对象

Java基础-注解 & 反射(十一)

/ * @author Daniel  *  */public class FanSheDemo2 {    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;//基本数据类型 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); //只要元素类型与维度一样,就是同一个class int[] a = new int[10]; int[] b = new int[100]; System.out.println (a.getClass ().hashCode ()); System.out.println (b.getClass ().hashCode ());    }}

运行结果显示为:
Java基础-注解 & 反射(十一)

2.2.4 Java内存分析

Java基础-注解 & 反射(十一)

2.3 创建运行时类的对象

2.3.1 了解类的加载过程

Java基础-注解 & 反射(十一)

2.3.2 类的加载与ClassLoader的理解

Java基础-注解 & 反射(十一)

/ * @author Daniel * java 内存模型分析 */public class JavaNeiCun {    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;  *   }  *   m= 100  */    }}class A{    static { System.out.println ("A类静态代码初始化"); m = 300;    }    static  int m = 100;    public A(){ System.out.println ("A类无参构造初始化");    }}

运行结果为:
Java基础-注解 & 反射(十一)

Java基础-注解 & 反射(十一)

2.3.3 什么时候会出现类初始化?

Java基础-注解 & 反射(十一)

public class ChuShiHuaDemo5 {    static { System.out.println ("main方法被加载");    }    public static void main(String[] args) throws ClassNotFoundException { //1.主动引用 Son son = new Son (); System.out.println ( son.getClass ().hashCode () ); //反射也会产生主动引用// Class c1 = Class.forName ( "fanshe.son" ); //System.out.println (c1); //不会产生类的引用的方法 System.out.println (son.b); System.out.println (son.M);    }}class Father{    static int b = 1;    static { System.out.println ("父类被加载");    }}class Son extends Father{    static { System.out.println ("子类被加载");    }    static int b = 10;    static final int M = 1;//常量并不会引起父类和子类的初始化}

运行结果为:
Java基础-注解 & 反射(十一)

2.4 类的加载与ClassLoader

2.4.1 类加载器的作用

Java基础-注解 & 反射(十一)
Java基础-注解 & 反射(十一)

package fanshe;/ * @author Daniel * 类加载器 */public class RelaxDemo5 {    public static void main(String[] args) throws ClassNotFoundException { //获取系统类的加载器 ClassLoader sld = ClassLoader.getSystemClassLoader (); System.out.println ( sld ); //获取系统类加载器的父类加载器——>扩展类加载器 ClassLoader parent = sld.getParent (); System.out.println ( parent ); //获取扩展类加载器的父类加载器——>根加载器(c/c++) ClassLoader parent1 = parent.getParent (); System.out.println ( parent1 ); //测试当前类是哪个加载器加载的 ClassLoader cld = Class.forName ( "fanshe.RelaxDemo5" ).getClassLoader (); System.out.println ( cld ); //测试jdk内置的类是谁加载的 ClassLoader cld1 = Class.forName ( "java.lang.Object" ).getClassLoader ();  System.out.println ( cld1 );  //如何获得类加载器加载的路径 System.out.println ( System.getProperty ( "java.class.path" ) ); /  * D:\develop\jdk\jre\lib\charsets.jar;  * D:\develop\jdk\jre\lib\deploy.jar;  * D:\develop\jdk\jre\lib\ext\access-bridge-64.jar;  * D:\develop\jdk\jre\lib\ext\cldrdata.jar;  * D:\develop\jdk\jre\lib\ext\dnsns.jar;  * D:\develop\jdk\jre\lib\ext\jaccess.jar;  * D:\develop\jdk\jre\lib\ext\jfxrt.jar;  * D:\develop\jdk\jre\lib\ext\localedata.jar;  * D:\develop\jdk\jre\lib\ext\nashorn.jar;  * D:\develop\jdk\jre\lib\ext\sunec.jar;  * D:\develop\jdk\jre\lib\ext\sunjce_provider.jar;  * D:\develop\jdk\jre\lib\ext\sunmscapi.jar;  * D:\develop\jdk\jre\lib\ext\sunpkcs11.jar;  * D:\develop\jdk\jre\lib\ext\zipfs.jar;  * D:\develop\jdk\jre\lib\javaws.jar;  * D:\develop\jdk\jre\lib\jce.jar;  * D:\develop\jdk\jre\lib\jfr.jar;  * D:\develop\jdk\jre\lib\jfxswt.jar;  * D:\develop\jdk\jre\lib\jsse.jar;  * D:\develop\jdk\jre\lib\management-agent.jar;  * D:\develop\jdk\jre\lib\plugin.jar;  * D:\develop\jdk\jre\lib\resources.jar;  * D:\develop\jdk\jre\lib\rt.jar;  * D:\develop\ideaIU-2018.2.5\idea_workspace\threadXian\out\production\threadXian;  * D:\develop\ideaIU-2018.2.5\idea_workspace\threadXian\src\com\xiancheng\lib\commons-io-2.6.jar;  * D:\develop\ideaIU-2018.2.5\idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar  */    }}

运行结果为:
Java基础-注解 & 反射(十一)

2.5 获取运行时类的完成结构

Java基础-注解 & 反射(十一)

2.6有了Class对象能做什么呢?

Java基础-注解 & 反射(十一)

2.7 调用运行时类的指定结构

2.7.1 调用指定的方法

Java基础-注解 & 反射(十一)
Java基础-注解 & 反射(十一)
SetAccessible
Java基础-注解 & 反射(十一)

总结:
(1)在实际的操作中,取得类的信息的操作代码,并不会经常开发。
(2)一定要熟悉Java.lang.reflect包的作用,反射机制。
(3)如何取得属性、方法、构造器的名称,修饰符等。

2.8 反射操作泛型(了解)

Java基础-注解 & 反射(十一)

2.9 反射操作注解

getAnnotations
getAnnotation

练习:ORM
了解什么是ORM?
Object relationship Mapping ———>对象关系映射
Java基础-注解 & 反射(十一)
类和表结构对应
属性和字段对应
对象和记录对应

要求:利用注解和反射完成类和表结构的映射关系

package fanshe;import java.lang.annotation.*;import java.lang.reflect.Field;public class RelaxAnnotation {    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName ( "fanshe.Student1" ); //通过反射获得注解 Annotation[] annotations = c1.getAnnotations (); for (Annotation annotation : annotations) {     System.out.println (annotation); } //获得注解的值value TableDaniel tableDaniel =(TableDaniel) c1.getAnnotation ( TableDaniel.class ); System.out.println ( tableDaniel.value () ); //获得指定类的注解 Field f = c1.getDeclaredField ( "name" ); FielDaniel annotation = f.getAnnotation ( FielDaniel.class ); System.out.println ( annotation.type () ); System.out.println ( annotation.columName () ); System.out.println ( annotation.length () );    }}@TableDaniel ( "db_student" )class Student1{    @FielDaniel (columName = "db_id",type = "int",length = 10)    private int id;    @FielDaniel (columName = "db_age",type = "int",length = 10)    private int age;    @FielDaniel (columName = "db_name",type = "varchar",length = 10)    private String name;    public Student1() {    }    public Student1(int id, int age, String name) { this.id = id; this.age = age; this.name = name;    }    public int getId() { return id;    }    public void setId(int id) { this.id = id;    }    public int getAge() { return age;    }    public void setAge(int age) { this.age = age;    }    public String getName() { return name;    }    public void setName(String name) { this.name = name;    }    @Override    public String toString() { return "Student1{" +  "id=" + id +  ", age=" + age +  ", name='" + name + '\'' +  '}';    }}//类名的注解@Target ( ElementType.TYPE )  //type 类@Retention ( RetentionPolicy.RUNTIME )@interface TableDaniel{    String value();}//属性的注解@Target ( ElementType.FIELD )//Field  属性@Retention ( RetentionPolicy.RUNTIME )@interface FielDaniel{    String columName();    String type();    int length();}

运行结果为:
Java基础-注解 & 反射(十一)

对应视频