反射

反射

动态语言

是一类在运行时可以改变其结构额语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或者是其他结构上的变化。

主要的动态语言有:C#\、JavaScript、PHP、Python等。

静态语言

运行时结构不变的语言就是静态语言

如:Java、C、C++

Java不是动态语言,但Java可以称为准动态语言。Java有一定的动态性,我们可以利用反射机制获得类似动态语言的特性。

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

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

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

正常方式:引入需要的"包类"名称->通过new实例化->取得实例化对象

反射方式:实例化对象->getClass()方法->得到完整的包类名称

Java反射机制提供的功能

在运行时判断任意一个对象所属的类

在运行时构造任意一个类的对象

在运行时判断任意一个类所具有的成员变量和成员方法

在运行时获取泛型信息

在运行时调用任意一个对象的成员变量和方法

在运行时处理注解

生成动态代理

优点:

可以实现动态创建对象和编译,体现出很大的灵活性

缺点:

对性能有影响,使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。

//通过反射获取类的class对象
Class c1 = Class.forName("com.cloudcore.pojo.User");
System.out.println(c1);
Class c2 = Class.forName("com.cloudcore.pojo.User");
Class c3 = Class.forName("com.cloudcore.pojo.User");
Class c4 = Class.forName("com.cloudcore.pojo.User");
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
//结果
class com.cloudcore.pojo.User
460141958
460141958
460141958

总结:

一个类在内存中只有一个Class对象

一个类被加载后,类的整个结构都会被封装在Class对象中。

获取Class类的方式

  1. 通过反射的Class.forName("com.cloudcore.pojo.User");方法

  2. 继承Object类,Object类中定义的getClass()方法,此方法被所有子类继承

    public final Class getClass()

    此方法的返回值类型是一个Class类,此类是Java反射的源头

Class类

获取Class类的实例

Class的创建方式

实体类

public class Person {
    String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + '}';
    }
}
public class Student extends Person{
    public Student(){
        this.name = "学生";
    }
}
public class Teacher extends Person{
    public Teacher(){
        this.name = "老师";
    }
}

测试类

public class TestReflex {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Person();
        System.out.println("这个人是:" + person.getName());
        //方式一:通过对象获得
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());//460141958

        //方式二:通过forName获得
        Class c2 = Class.forName("com.cloudcore.pojo.Person");
        System.out.println(c2.hashCode());//460141958

        //方式三:通过类名.class获得
        Class<Person> c3 = Person.class;
        System.out.println(c3.hashCode());//460141958

        //方式四:基本内置类型的包装类都有一个Type属性
        Class<Integer> type = Integer.TYPE;
        System.out.println(type);//int

        //获得父类类型
        Class father = c1.getSuperclass();
        System.out.println(father);//class java.lang.Object
    }
}

结果:

这个人是:null
460141958
460141958
460141958
int
class java.lang.Object
哪些类型可以有class对象

public class TestType {
    public static void main(String[] args) {
        //所有类型的class
        //类
        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;
        //void
        Class c8 = void.class;
        //类
        Class c9 = 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 java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.annotation.ElementType
class java.lang.Integer
void
class java.lang.Class
内存分析

package com.cloudcore.test;

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

/**
 * @Author: hepeng
 * @Date: 2021/9/23 0:16
 */
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("com.cloudcore.pojo.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);//可以找到全部属性
        }
        //private java.lang.String com.cloudcore.pojo.User.name
        // private int com.cloudcore.pojo.User.id
        // private int com.cloudcore.pojo.User.age
        System.out.println("-------------------------------------------------");
        //获得指定属性的值
        Field name = c1.getDeclaredField("name");
        System.out.println(name);

        System.out.println("-------------------------------------------------");
        //获得类的方法
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
            System.out.println(method);//获得本类及其父类的全部public方法
        }

        Method[] declaredMethods = c1.getDeclaredMethods();//获得本类的所有方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        System.out.println("-------------------------------------------------");
        //获得指定方法
        Method getName = c1.getMethod("getName", null);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

        //获得指定的构造器
        System.out.println("-------------------------------------------------");
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
    }
}

结果:

com.cloudcore.pojo.User
User
-------------------------------------------------
private java.lang.String com.cloudcore.pojo.User.name
private int com.cloudcore.pojo.User.id
private int com.cloudcore.pojo.User.age
-------------------------------------------------
private java.lang.String com.cloudcore.pojo.User.name
-------------------------------------------------
public java.lang.String com.cloudcore.pojo.User.toString()
public java.lang.String com.cloudcore.pojo.User.getName()
public int com.cloudcore.pojo.User.getId()
public void com.cloudcore.pojo.User.setName(java.lang.String)
public void com.cloudcore.pojo.User.setId(int)
public int com.cloudcore.pojo.User.getAge()
public void com.cloudcore.pojo.User.setAge(int)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public java.lang.String com.cloudcore.pojo.User.toString()
public java.lang.String com.cloudcore.pojo.User.getName()
public int com.cloudcore.pojo.User.getId()
public void com.cloudcore.pojo.User.setName(java.lang.String)
public void com.cloudcore.pojo.User.setId(int)
public int com.cloudcore.pojo.User.getAge()
public void com.cloudcore.pojo.User.setAge(int)
-------------------------------------------------
public java.lang.String com.cloudcore.pojo.User.getName()
public void com.cloudcore.pojo.User.setName(java.lang.String)
-------------------------------------------------
public com.cloudcore.pojo.User()
public com.cloudcore.pojo.User(java.lang.String,int,int)
public com.cloudcore.pojo.User()
public com.cloudcore.pojo.User(java.lang.String,int,int)

注意:

不能直接操作私有属性,我们需要关闭程序的安全检测,属性或方法的setAccessible(true)

创建对象newnstance()

方法的调用invoke

反射操作泛型

posted @ 2021-09-25 11:34  正在努力的澎澎  阅读(33)  评论(0)    收藏  举报