反射

反射

  • 反射让java变为准动态语言

  • 动态语言:在运行的时候可以根据某些条件改变自身结构

  • 静态语言:运行时不可变的就是静态语言

  • Reflection(反射):反射机制允许程序在执行期借助于Reflection API取的任何类的内部信息(类名,类的接口,类的方法,类的属性等等)并能直接操作对象的内部属性及方法

    Class c = Class.forName("java.lang.String")

  • 加载完类之后,在堆内存的方法区就产生了一个Class类型的对象(一个类只有一个Class对象)这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子可以看到类的结构,所以,我们形象的称之为反射

package com.Lv.reflection;

/**
 * @Author: Lv
 * @Description:反射
 * @Vision: 1.0
 * @Date: Created in 9:59 2020/7/6
 */
public class Test01 {

    public static void main(String[] args) throws ClassNotFoundException {
        //通过反射获取Class对象
        Class c1 = Class.forName("com.Lv.reflection.User");
        System.out.println(c1);

        //一个类在内存中只有一个Class对象
        //一个类在被加载之后,类的整个结构都会被封装在Class对象中
        Class c2 = Class.forName("com.Lv.reflection.User");
        Class c3 = Class.forName("com.Lv.reflection.User");
        Class c4 = Class.forName("com.Lv.reflection.User");
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());
    }
}
//实体类
class User {
    private int id;
    private String name;
    private int age;

    public User() {
    }

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        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;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Class类

对象照镜子后得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE都为其保留一个不变的Class类型的对象。一个Class对象包含了特定某个结构的有关信息。

  • Class本身也是一个类
  • Class对象只能由系统建立对象
  • 一个加载的类在JVM中值会有一个Class实例
  • 一个Class对象对应的是一个加载到JVM中的一个.class文件
  • 每个类的实例都会记得自己是由哪个Class实例所生成
  • 通过Class可以完整地得到一个类中所有被加载的结构
  • Class类是Reflection的根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象

Class类的常用方法

  • static ClassforName(String name):返回指定类名的Class对象
  • Object newInstance():调用缺省构造函数,返回Class对象的一个实例
  • getName:返回此Class所表示的实体(类、接口、数组类或void)的名称
  • Class getSuperClass():返回当前对象父类的Class对象
  • Class[] getinterfaces():获取当前对象的接口
  • ClassLoader getClassLoader():返回该类的类加载器
  • Class[] getConstructors():返回一个包含某些Constructor对象的数组
  • Method getMethod(String name,Class... T):返回一个Method对象,此对象的形参类型为paramType
  • Field[] getDeclaredFields():返回Field对象的一个数组

获取Class类的实例

  1. 若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高

    Class clazz = Person.class;

  2. 已知某个类的实例,调用该实例的getClass()方法获取Class对象

    Class clazz = person.getClass();

  3. 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException

    Class clazz = Class.forName("com.Lv.reflection.User");

  4. 内置基本数据类型可以直接用类名.Type

  5. 还可以用ClassLoader

package com.Lv.reflection;

/**
 * @Author: Lv
 * @Description:几种获得Class实例的方法
 * @Vision: 1.0
 * @Date: Created in 10:44 2020/7/6
 */
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        //第一种,通过对象获得
        Class c1 = person.getClass();
        System.out.println(c1);

        //第二种,Class.forName
        Class c2 = Class.forName("com.Lv.reflection.Student");
        System.out.println(c2.hashCode());

        //第三种,通过类名.class获得
        Class c3 = Teacher.class;
        System.out.println(c3);

        //第四种,基本数据类型的包装类.Type获得
        Class c4= Integer.TYPE;
        System.out.println(c4);

        //第五种,获得父类类型
        Class c5 = c2.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 = "老师";
    }
}

哪些类型可以有Class对象?

  • class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
  • interface:接口
  • []:数组
  • enum:枚举
  • annotation:注解@interface
  • prinmitive type:基本数据类型
  • void
package com.Lv.reflection;

import java.lang.annotation.ElementType;

/**
 * @Author: Lv
 * @Description:哪些类型有class对象
 * @Vision: 1.0
 * @Date: Created in 11:09 2020/7/6
 */
public class Test03 {
    public static void main(String[] args) {
        Class c1 = Integer.TYPE; //基本数据类型
        Class c2 = void.class;   //void
        Class c3 = ElementType.class;   //枚举
        Class c4 = Comparable.class;   //接口
        Class c5 = Override.class;   //注解
        Class c6 = String[].class;   //一维数组
        Class c7 = String[][].class;   //二维数组
        Class c8 = Class.class;   //Class
        Class c9 = Object.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());

    }
}

通过反射获取类的信息

package com.Lv.reflection;

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

/**
 * @Author: Lv
 * @Description:获得类的信息
 * @Vision: 1.0
 * @Date: Created in 13:30 2020/7/6
 */
public class Test04 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("com.Lv.reflection.User");

        //获得类的名字
        System.out.println(c1.getName());   //包名+;类名
        System.out.println(c1.getSimpleName());   //类名
        System.out.println("==============================");

        //获得类的属性
        Field[] fields = c1.getFields();   //只能获得public属性
        for (Field field : fields) {
            System.out.println(field);
        }
        Field[] declaredFields = c1.getDeclaredFields();   //获得全部属性
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        Field name = c1.getDeclaredField("name");   //获得指定名称的属性
        System.out.println(name);
        System.out.println("==============================");


        //获得类的方法
        Method[] methods = c1.getMethods();     //获得public属性的方法,包括Object类
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("==============================");
        Method[] declaredMethods = c1.getDeclaredMethods();   //获得本类全部方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        Method setName = c1.getDeclaredMethod("setName", String.class);
        System.out.println(setName);

        //获得指定构造器
    }
}

通过反射动态的创建对象及操作属性

package com.Lv.reflection;

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

/**
 * @Author: Lv
 * @Description:获得类的信息
 * @Vision: 1.0
 * @Date: Created in 13:30 2020/7/6
 */
public class Test04 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("com.Lv.reflection.User");

        //获得类的名字
        System.out.println(c1.getName());   //包名+;类名
        System.out.println(c1.getSimpleName());   //类名
        System.out.println("==============================");

        //获得类的属性
        Field[] fields = c1.getFields();   //只能获得public属性
        for (Field field : fields) {
            System.out.println(field);
        }
        Field[] declaredFields = c1.getDeclaredFields();   //获得全部属性
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        Field name = c1.getDeclaredField("name");   //获得指定名称的属性
        System.out.println(name);
        System.out.println("==============================");


        //获得类的方法
        Method[] methods = c1.getMethods();     //获得public属性的方法,包括Object类
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("==============================");
        Method[] declaredMethods = c1.getDeclaredMethods();   //获得本类全部方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        Method setName = c1.getDeclaredMethod("setName", String.class);
        System.out.println(setName);

        //获得指定构造器
    }
}

通过反射操作注解

package com.Lv.reflection;

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

/**
 * @Author: Lv
 * @Description:通过反射操作注解
 * @Vision: 1.0
 * @Date: Created in 16:26 2020/7/6
 */
public class Test07 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("com.Lv.reflection.Student01");

        //通过反射获得注解
        Annotation[] annotations = c1.getDeclaredAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //通过反射获得注解的值
        classLv cl = (classLv)c1.getAnnotation(classLv.class);
        System.out.println(cl.value());
        
        //获得属性注解的值
        Field name = c1.getDeclaredField("name");
        fieldLv fieldLv = name.getAnnotation(fieldLv.class);
        System.out.println(fieldLv.columnName());
        System.out.println(fieldLv.type());
        System.out.println(fieldLv.length());
    }
}
@classLv("db_student")   //将定义的注解加上去
//定义一个实体类
class Student01 {     
    @fieldLv(columnName = "db_id",type = "int", length = 10)
    private int id;
    @fieldLv(columnName = "db_name",type = "varchar", length = 10)
    private String name;
    @fieldLv(columnName = "db_age",type = "int", length = 10)
    private int age;

    @Override
    public String toString() {
        return "Student01{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        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 Student01(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Student01() {
    }
}

//自定义的类注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface classLv{
    String value();
}
//自定义的属性注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface fieldLv{
    String columnName();
    String type();
    int length();
}
posted @ 2020-07-06 11:43  我是橘子  阅读(150)  评论(0)    收藏  举报