前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >反射相关

反射相关

作者头像
Li_XiaoJin
发布2022-06-10 20:34:19
1290
发布2022-06-10 20:34:19
举报
文章被收录于专栏:Lixj's BlogLixj's Blog

反射是Java程序开发语言的特征之一,它允许运行中的Java程序获取自身的信息,并且可以操作类或对象的内部属性。

官方解释: Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions.

The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control.

 简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。

程序中一般的对象的类型都是在编译期就确定下来的,而Java反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。

 反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。

Java反射框架主要提供的功能:

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

2、在运行时构造一个类的对象

3、在运行时判断任意一个类具有的成员变量和方法(通过反射甚至可以调用private方法)

4、在运行时调用任意一个对象的方法 注意:是在运行时而不是编译时、

Java反射机制是在运行状态中,对任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及调用对象的方法的功能成为Java语言的反射机制。

反射就是把java类中的各种成分映射成一个个的Java对象 例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述) 如图是类的正常加载过程:反射的原理在与class对象。 熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

放射的基本运用

介绍一下基本反射功能的实现(反射相关的类一般都在java.lang.relfect包里)。

1、三种获取Class对象的方法

(1)使用Class类的forName静态方法、 在JDBC开发中常用此方法加载数据库驱动: 要使用全类名来加载这个类,一般数据库驱动的配置信息会写在配置文件中。加载这个驱动前要先导入jar包

代码语言:javascript
复制
 Class.forName(driver);

(2)直接获取某一个对象的Class

代码语言:javascript
复制
    //Class<?>是一个泛型表示,用于获取一个类的类型。
    Class<?> klass = int.class;
    Class<?> classInt = Integer.TYPE;

(3)调用某个对象的getClass()方法

代码语言:javascript
复制
StringBuilder str = new StringBuilder("123");
Class<?> klass = str.getClass();

判断是否为某个类的实例

一般使用instanceof关键字来判断是否为某个类的实例;也可以使用反射中Class对象的isInstance()方法来判断是否为某个类的实例,它是一个Native方法

代码语言:javascript
复制
public native boolean isInstance(object obj);

创建实例

通过反射生成实例有两种方式: (1)使用Class对象的newInstance()方法来创建对象对应类的实例

注意:利用newInstance创建对象,调用的类必须有无参的构造函数

代码语言:javascript
复制
            Class c = String.class;
            Object object = c.newInstance();

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

代码语言:javascript
复制
            Class c = String.class;
            Constructor con = c.getConstructor(String.class);
            Object obj = con.newInstance("123");
            System.out.println(obj);

获取方法

获取对象的方法主要有以下: (1)getDeclaremethods()返回类或接口声明的所有方法,

包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法

代码语言:javascript
复制
    public Method[] getDeclaredMethods() throws SecurityException 

(2)getMethods()方法返回某个类的所有公用(public)方法

包括其继承类的公用方法

代码语言:javascript
复制
    public Method[] getMethods() throws SecurityException

(3)getMethods()方法返回某个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象

代码语言:javascript
复制
    public Method getMethod(String name, Class<?>... parameterTypes)

反射创建实例的三种方法

  • 第一种表示方式

实际在告诉我们任何一个类都有一个隐含的静态成员变量class Class class1 = Foo.class;

  • 第二种表示方式

已经知道该类的对象通过getClass方法 Class class2 = foo1.getClass(); System.out.println(class1==class2);//true'

  • 第三种表达方式 Class class3 = null; try { class3 = Class.forName("com.imooc.reflect.Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); }

System.out.println(class2==class3);//true

  • 需要有无参数的构造方法

Foo foo = (Foo) class1.newInstance();//需要强转

代码例子:

代码语言:javascript
复制
public class ReflectGetClass {

    /**
     * 法1:通过对象---对象.getClass()来获取c(一个Class对象)
     */
    @Test
    public void get1(){
        Person p=new Person("Jack", 23);
        Class c=p.getClass();//来自Object方法
    }

    /**
     * 法2:通过类(类型)---任何数据类型包括(基本数据类型)都有一个静态的属性class ,他就是c 一个Class对象
     */
    @Test
    public void get2(){
        Class c=Person.class;
        Class c2=int.class;
    }

    /**
     * 法3:通过字符串(类全名 )---能够实现解耦:Class.forName(str)
     */
    @Test
    public void get3(){
        try {
            Class c=Class.forName("cn.hncu.reflect.test.Person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可 Links: https://cloud.tencent.com/developer/article/2020478

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 放射的基本运用
  • 判断是否为某个类的实例
  • 创建实例
  • 获取方法
  • 反射创建实例的三种方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档