注解与反射02-反射

举报
盼盼 发表于 2021/04/19 09:17:01 2021/04/19
【摘要】 1 反射基本理解1.2 反射意义:    1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。    (2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载...

1 反射基本理解
1.2 反射意义:

    1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。

    (2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

Class对象的由来是将.class文件读入内存,并为之创建一个Class对象,所以一个类在内存中只存在一个 Class 对象。

反射的用途

    1、反编译:.class–>.java
    2、通过反射机制访问java对象的属性,方法,构造方法等
    3、反射最重要的用途就是开发各种通用框架。比如很多框架(Spring)都是配置化的(比如通过XML文件配置Bean),为了保证框架的通用性,他们可能需要根据配置文件加载不同的类或者对象,调用不同的方法,这个时候就必须使用到反射了,运行时动态加载需要的加载的对象。

例如:Class.forName(“com.mysql.jdbc.Driver”); // 动态加载mysql驱动,就是使用反射机制
1.2 反射机制常用的类:
Java.lang.Class;
Java.lang.reflect.Constructor;
Java.lang.reflect.Field;
Java.lang.reflect.Method;
Java.lang.reflect.Modifier;
2 反射的常用使用
2.1 Class三种获得方法

    1 Object–>getClass
    2 任何数据类型(包括基本的数据类型)都有一个“静态”的class属性,getClass();
    3 通过class类的静态方法:forName(String className)

public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        //第一种方式获取Class对象
        User user = new User();//new一个 User 对象,一个 Class 对象
        Class c1 = user.getClass();//获取Class对象
        System.out.println(c1.getName()); //com.hncj.User
        
        //第二种方式获取Class对象
        Class c2 = User.class;
        System.out.println(c1.getName());//com.hncj.User

        //第三种方式获取Class对象
        Class c3 = Class.forName("com.hncj.User");
        System.out.println(c3.getName());//com.hncj.User

        System.out.println(c1==c2&&c1==c3); //true
    }
}

   

在运行期间,一个类,只有一个Class对象产生,所以打印结果都是true

    第一种方式,对象都有了还要反射干什么?
    第二种方式,需要导入类包,依赖太强,不导包就抛编译错误。
    第三种(常用)方式,一个字符串可以传入也可以写在配置文件中等多种方法。需要抛出异常

2.2 判断是否为某个类的实例

使用instanceof 关键字来判断是否为某个类的实例

public native boolean isInstance(Object obj);

    1

2.3 创建实例

通过反射来生成对象主要有两种方法

    使用Class对象的newInstance()方法来创建Class对象对应类的实例

Class<?> c = String.class;
Object str = c.newInstance();

    1
    2

    先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建对象,这种方法可以用指定的构造器构造类的实例

//获取Class对象
Class<?> str = String.class;
//通过Class对象获取指定的Constructor构造器对象
Constructor constructor=c.getConstructor(String.class);
//根据构造器创建实例:
Object obj = constructor.newInstance(“hello reflection”);

   
   

3 反射深入使用(获取类的运行时结构)
3.1 获取构造方法

    1 批量获取
    public Constructor[] getConstructors():所有"公有的"构造方法
    public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
     
    2 单个获取
    public Constructor getConstructor(Class… parameterTypes):获取单个的"公有的"构造方法:
    public Constructor getDeclaredConstructor(Class… parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

调用构造方法:

Constructor–>newInstance(Object… initargs)

Constructor constructor = c1.getDeclaredConstructor(String.class, int.class);
User user2 = (User) constructor.newInstance("李中祥", 23);
System.out.println(user2);


3.2 获取类名

Class c1 = Class.forName("com.hncj.User");
//获取类名
System.out.println(c1.getName()); //获取包名+类名  com.hncj.User
System.out.println(c1.getSimpleName()); //获取类名 User

 

    getName() 获取包名+类名
    getSimpleName() 获取简单的类名称

3.3 获取成员变量

//批量获取类属性
Field[] fields = c1.getFields(); //获取public属性
for(Field field : fields){
  System.out.println(field);
}
System.out.println("==========");
fields = c1.getDeclaredFields(); //找到全部属性(private,public)
for(Field field : fields){
  System.out.println(field);
}


//单个 获取指定属性的值
Field b = c1.getField("b"); //获取指定字段(private,public)
System.out.println(b);
System.out.println("++++++++++++++++++");

Field b1 = c1.getDeclaredField("b"); //获取指定字段(private,public)
System.out.println(b1);

 

    1 批量获取属性
    Field[] getFields(); 获取所有public属性
    Field[] getDeclaredFields(); 获取所有属性(private.public)
     
    2 单个获取属性
    Field getField(String fieldName)
    Field getDeclaredField(String field) 获取指定字段

3.4 获取成员方法

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

System.out.println("++++++++++++++++++");
methods = c1.getDeclaredMethods(); //本类所有方法(包含public,private)
for(Method method : methods){
    System.out.println("方法:" + method);
}

   

    1.批量的:
    Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
    Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
     
    2.获取单个的:
    Method getMethod(String name,Class<?>… parameterTypes):
    参数:
    name : 方法名;
    Class … : 形参的Class类型对象
    Method getDeclaredMethod(String name,Class<?>… parameterTypes)

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。