反射

反射

正常方式 :引入需要的"包类"名称 => new 对象 => 实例化对象
反射方式 :实例化对象 => getClass() => 得到完整的"包类"名称 


反射机制的功能:
	在运行时 ,判断任意一个对象所属的类
    在运行时 ,构造任意一个类对象
    在运行时 ,判断任意一个类所具有的成员变量和方法
    在运行时 ,获取泛型信息
    在运行时 ,调用任意一个对象的成员变量和方法
    在运行时 ,处理注解
    生成动态代理
    
 反射的优点:
 	实现动态创建对象和编译,体现出很大的灵活性
 缺点:
 	对性能有影响。反射是一种解释操作,告诉JVM它会满足我们所需要的要求,
    所以反射总是慢于直接执行相同的操作

Class类

Class本身也是一个类,只能由系统建立对象
一个加载的类在JVM中只有一个Class实例
一个Class对象对应的是一个加载到JVM中的一个.class文件
每个类的实例都会记得自己是由哪个Class实例所生成
通过Class可以完整地得到一个类中所有被加载的结构

获取Class对象的几种方式

alt

package com.gwq.pojo;

public class Mytest {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("我是"+person.Name);

        //方式一 :对象.getClass()
        Class c1 = person.getClass();

        //方式二 :Class.forName(全类名)
        Class c2 = Class.forName("com.gwq.pojo.Student");

        //方式三 :类名.class
        Class c3 = Student.class;

        System.out.println(c1==c2 && c2==c3);	//true
        //获得父类类型
        Class c5 = c1.getSuperclass();
        
    }
}




class Person{
    String Name;
    public Person() {
    }
    public Person(String name) {
        Name = name;
    }
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        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类内存过程

1.Class基本数据结构存储在方法区(堆)中
2.唯一Class对象存放在堆中
3.合并Class中的静态数据,执行类构造器clint()方法
4.产生实例对象,对象引入存放在栈中,和main一起

什么时候会发生初始化

alt

类加载器

分类:
Bootstap ClassLoader	引导类加载器 :负责Java核心库
Extension Classloader	扩展类加载器
System Classloader		系统类加载器

public class ClassLoader {
    public static void main(String[] args) {
        //获取系统类的加载器             AppClassLoader
        java.lang.ClassLoader systemClassLoader = java.lang.ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        //获取系统类加载器的父类加载器    ==>     扩展类加载器  ExtClassLoader
        final java.lang.ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);

        //获取扩展类加载器的父类加载器    ==>     根加载器
        final java.lang.ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);    //由于是C++编写的,所以null

    }
}         

获取Class结构

package com.gwq.pojo;

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

public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        //获取User 的 Class对象
        Class c1 = Class.forName("com.gwq.pojo.User");

        //获取类名
        System.out.println(c1.getName());       //全类名
        System.out.println(c1.getSimpleName()); //获得类名

        //获取类的属性
        Field[] fields = c1.getFields();    //获取public属性
        fields = c1.getDeclaredFields();    //获取全部属性

        for (Field field : fields) {
            System.out.println(field);
        }

        //获得指定public属性,如果类中没有指定public修饰的属性,则报NoSuchFieldException
        //Field name = c1.getField("Name");

        //获得指定public属性.如果类中没有指定属性,则报NoSuchFieldException
        Field name = c1.getDeclaredField("Name");
        System.out.println(name);

        //获取本类以及父类的全部public方法
        Method[] methods = c1.getMethods();
        //获得本类的所有方法
        methods = c1.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        //获得指定方法
        Method getName = c1.getMethod("getName",null);
        Method setName = c1.getMethod("setName", String.class);

    }
}

动态创建对象执行方法

package com.gwq.pojo;

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

public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获取Class对象
        Class c1 = Class.forName("com.gwq.pojo.User");

        //实例化对象
        //1.class.newInstance(),本质调用了类的无参构造器
        //User user = (User)c1.newInstance();

        //2.通过构造器实例化对象
        Constructor constructor = c1.getDeclaredConstructor(String.class, int.class);
        constructor.setAccessible(true); //开启暴力访问权限构造器
        User user = (User) constructor.newInstance("张三", 5);
        System.out.println(user);

        //通过反射执行一个方法
        //1.获取方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        setName.setAccessible(true);    //开启暴力访问权限方法
        setName.invoke(user,"李白");
        System.out.println(user);

        //2.获取属性
        Field age = c1.getDeclaredField("age");
        age.setAccessible(true);        //开启暴力访问权限属性
        age.set(user,100);
        System.out.println(user);

    }
}

获取泛型信息

alt

反射操作注解

alt

全部评论

相关推荐

04-18 15:58
已编辑
门头沟学院 设计
kaoyu:这一看就不是计算机的,怎么还有个排斥洗碗?
点赞 评论 收藏
分享
05-20 13:59
门头沟学院 Java
米黑子米黑子:你这个成绩不争取下保研?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务