反射 Reflect

介绍

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

早期,new一个对象的时候,先根据被new的【类的名称】找寻该类的字节码文件,
然后加载进内存,并自动创建该【字节码文件对象】 ,接着创建该字节文件对应的【该类的对象】

现在,同样是先根据被new的【类的名称】找寻该名称的类文件,然后加载进内存,最后通过Class对象的newInstance方法产生【该类的对象】

PS:字节码文件即class文件,是经过编译器预处理过的一种文件,是JAVA的执行文件存在形式。它本身是二进制文件,但是不可以被系统直接执行,而是需要虚拟机解释执行,由于被预处理过,所以比一般的解释代码要快,但是仍然会比系统直接执行的慢。

示例


public class ReflectDemo {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,

            NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {

        //三种获取对象运行时类的方法

        Person person = new Person();

        Class<? extends Person> clazz = person.getClass();//获取此 Object 的运行时类

        System.out.println(clazz == new Person().getClass());//true。两个对象的运行时类是同一个类

        System.out.println(clazz == Person.class);//true。任何数据类型的静态的属性【.class】表示其对应的Class对象

        System.out.println(clazz == Class.forName("cn.itcast.bean.Person"));//true。只要通过给定的类的字符串名称即可,这种最常用!

        System.out.println("----------------------------1-----------------------------");

        //通过反射获取【类】的字段信息

        Field publicField = clazz.getField("age");//获取全部公有的字段,包含父类的字段。注意私有字段不能通过这种方式获取

        Field allField = clazz.getDeclaredField("name");// 获取本类中定义的公有所有字段,包含私有字段。注意不能获取父类的字段。

        System.out.println(publicField);//public int cn.itcast.bean.Person.age

        System.out.println(allField);//private java.lang.String cn.itcast.bean.Person.name

        System.out.println(Arrays.toString(clazz.getFields()));//[public int cn.itcast.bean.Person.age]

        System.out.println(Arrays.toString(clazz.getDeclaredFields()));//[age, name]

        System.out.println("----------------------------2-----------------------------");

        //通过反射访问指定【对象】的指定字段

        Person person2 = clazz.newInstance();

        allField.setAccessible(true);//如果设置为true,则表示可以忽略访问权限的限制,直接访问此成员。设为true可以直接访问私有字段。

        allField.set(person2, "包青天");//将【指定对象】上的此 Field 对象表示的【字段】设置为指定的值

        String mName = (String) allField.get(person2);//注意:返回的是【指定对象】上此 Field 表示的【字段的值】

        System.out.println(mName + "--" + person2.getName());//包青天--包青天

        //通过反射获取【类】的方法信息

        Method paramMethod = clazz.getMethod("paramMethod", int.class);//获取方法名为paramMethod,参数列表类型为int的方法

        Method noParamMethod = clazz.getMethod("show");//获取参数列表为空的方法。注意:不要使用这种形式("show",null)

        Method privateMethod = clazz.getDeclaredMethod("privateMethod");

        System.out.println(paramMethod);//public void cn.itcast.bean.Person.paramMethod(int)

        System.out.println(noParamMethod);//public void cn.itcast.bean.Person.show()

System.out.println(privateMethod);//private void cn.itcast.bean.Person.privateMethod()

        System.out.println(Arrays.toString(clazz.getMethods()));//和获取字段一样,获取的是包括从父类或父接口继承的全部公有方法

        System.out.println(Arrays.toString(clazz.getDeclaredMethods()));//和获取字段一样,获取的是在本类中定义的所有方法

        System.out.println("----------------------------3-----------------------------");

        //通过反射访问指定【对象】的指定方法

        Person person3 = clazz.newInstance();

        privateMethod.setAccessible(true);//设为true后可以直接调用对象的私有方法。

        privateMethod.invoke(person3);//私有方法:null。对带有【指定参数】的【指定对象】调用由此 Method 对象表示的底层方法

        paramMethod.invoke(person3, 1989);//有参方法,参数为:1989

        System.out.println("----------------------------4-----------------------------");

        //通过反射访问类的构造方法

        clazz.newInstance().show();//公共方法。默认调用无参构造函数产生对象

        Constructor<? extends Person> publicConstructor = clazz.getConstructor(String.class, int.class); //共有构造方法

        publicConstructor.newInstance("小明", 38).paramMethod(2016);//有参方法,参数为:2016。调用指定有参构造函数产生对象

        Constructor<? extends Person> privateConstructor = clazz.getDeclaredConstructor(int.class);//私有构造方法

        privateConstructor.setAccessible(true);

        privateConstructor.newInstance(50).paramMethod(50);//有参方法,参数为:50

        System.out.println(Arrays.toString(clazz.getConstructors()));//[Person(),Person(int),Person(String,int)]

        System.out.println(Arrays.toString(clazz.getDeclaredConstructors()));//[Person(),Person(int),Person(String,int)]

    }

}

反射所指向的对象


package cn.itcast.bean;

public class Person {

    public int age;//公共成员

    private String name;//私有成员

    public String getName() {

        return name;

    }

    public Person() {//无参构造方法

        this(0);

    }

    private Person(int age) {//私有构造方法

        super();

        this.age = age;

    }

    public Person(String name, int age) {//有参构造方法

        super();

        this.age = age;

        this.name = name;

    }

    @SuppressWarnings("unused")

    private void privateMethod() {//私有方法

        System.out.println("私有方法:" + name);

    }

    public void show() {//公共方法

        System.out.println("公共方法");

    }

    public void paramMethod(int num) {//有参方法

        System.out.println("有参方法,参数为:" + num);

    }

    public static void staticMethod() {//静态成员

        System.out.println("静态成员");

    }

}

运行结果


true

true

true

----------------------------1-----------------------------

public int cn.itcast.bean.Person.age

private java.lang.String cn.itcast.bean.Person.name

[public int cn.itcast.bean.Person.age]

[public int cn.itcast.bean.Person.age, private java.lang.String cn.itcast.bean.Person.name]

----------------------------2-----------------------------

包青天--包青天

public void cn.itcast.bean.Person.paramMethod(int)

public void cn.itcast.bean.Person.show()

private void cn.itcast.bean.Person.privateMethod()

[public java.lang.String cn.itcast.bean.Person.getName(), public void cn.itcast.bean.Person.paramMethod(int), public void cn.itcast.bean.Person.show(), public static void cn.itcast.bean.Person.staticMethod(), 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 final void java.lang.Object.wait() throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), 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 cn.itcast.bean.Person.getName(), public void cn.itcast.bean.Person.paramMethod(int), public void cn.itcast.bean.Person.show(), private void cn.itcast.bean.Person.privateMethod(), public static void cn.itcast.bean.Person.staticMethod()]

----------------------------3-----------------------------

私有方法:null

有参方法,参数为:1989

----------------------------4-----------------------------

公共方法

有参方法,参数为:2016

有参方法,参数为:50

[public cn.itcast.bean.Person(), public cn.itcast.bean.Person(java.lang.String,int)]

[private cn.itcast.bean.Person(int), public cn.itcast.bean.Person(), public cn.itcast.bean.Person(java.lang.String,int)]

来自为知笔记(Wiz)

时间: 2024-11-05 04:08:57

反射 Reflect的相关文章

go语言之行--接口(interface)、反射(reflect)详解

一.interface简介 interface(接口)是golang最重要的特性之一,Interface类型可以定义一组方法,但是这些不需要实现.并且interface不能包含任何变量. 简单的说: interface是方法的集合 interface是一种类型,并且是指针类型 interface的更重要的作用在于多态实现 interface定义 type 接口名称 interface { method1 (参数列表) 返回值列表 method2 (参数列表) 返回值列表 ... } interf

Golang的反射reflect深入理解和示例

编程语言中反射的概念 在计算机科学领域,反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 每种语言的反射模型都不同,并且有些语言根本不支持反射.Golang语言实现了反射,反射机制就是在运行时动态的调用对象的方法和属性,官方自带的reflect包就是反射相关的,只要包含这个包就可以使用. 多插一句,

类的加载到反射reflect

类的加载: 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载.连接.初始化这三个步骤来实现对这个类进行初始化. 加载: 就是指将class文件加载进入内存,并为之创建一个Class对象 任何类被使用时,系统都会创建一个Class对象 连接: 验证: 是否有正确的内部结构,并且和其他类协调一致 准备: 负责为类的静态成员分配内存,并设置默认初始化值 解析: 将类的二进制数据中的符号引用替换为直接引用 初始化:就是以前我们讲过的初始化步骤 类初始化的时机: 创建类的实例 访问类的静

(java)从零开始之-反射Reflect

反射: 当一个字节码文件加载到内存的时候,jvm会对该字节码进行解剖,然后会创建一个对象的Class对象,把字节码文件的信息全部都存储到该Class对象中,我们只要获取到Class对象,我们就可以使用字节码对象设置对象的属性或者调用对象的方法等操作 这里记录下反射的简单使用,方便查阅 1 /******************* 2 获取class 3 *******************/ 4 //Class clazz = Person.class;//方式一,通过类名获取 5 //Cla

JAVA编程之——反射Reflect

说到反射,首先要说一下Java中的类和对象. 在Java中万事万物皆对象(有两个 例外,一个是普通数据类型,另一个是静态的东西,静态的东西不是对象的,是属于类的). 在Java中,类也是对象,类是java.lang.class类的实例对象,即所谓There is a class named Class. 以下代码说明了Java中Class类的实例对象的三种表达方式 package org.guyezhai.reflect; public class ClassDemo1 { public sta

java 反射(reflect)总结,附对象打印工具类

java反射机制认知 java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取类的信息以及动态调用对象的方法的功能称为java语言的反射机制Reflection. 这就说明:Java程序可以加载一个编译期间完全未知的class,获悉其完整构造,并生成其对象实体.或对其fields设值.或唤起其methods.虽然java并不是动态语言. 如何达到上述目的,是本文探讨的内容.本文将介绍Reflection A

java中【反射(Reflect)】的常见应用场景

简介: 总结于imooc课程:     http://www.imooc.com/learn/199   本文通过几个简单的例子,介绍Class类的使用,方法和成员变量的反射,以及通过反射了解集合泛型的本质等知识. 1.Class类的使用 /** * 使用java.lang.Class类动态加载一个类,编译时不对类是否存在以及对错进行检查,运行时检查 */ public class OfficeBetter { public static void main(String[] args) { a

反射 Reflect Modifier 修饰符工具类

在查看反射相关的Class.Field .Constructor 等类时,看到他们都有这样一个方法:getModifiers():返回此类或接口以整数编码的 Java 语言修饰符.如需要知道返回的值所代表的意思,则需要用到 java.lang.reflect.Modifier 这个类,这个类提供了 static 方法和常量,可以对类和成员访问修饰符进行解码. 既然是位于 java.lang.reflect 下,那说明一般是在动态加载过程中.使用java反射对某些类进行过滤时会用到,一般开发并不是

go的反射reflect访问struct结构注意问题

通过反射查看struct里面结构信息: type Point struct { X int Y string } func main() { po := Point{3, "ddd"} s := reflect.ValueOf(&po).Elem() for i := 0; i < s.NumField(); i++ { f := s.Field(i) fmt.Printf(" %s %v \n", f.Type(), f.Interface()) }

Java基础——反射 reflect

a { text-decoration: none; color: inherit } * { margin: 0; padding: 0 } body { text-indent: 2rem } .on { margin: 10px 0; cursor: pointer; color: white; text-indent: 2rem } .on2 { background-color: deeppink; font: bold 24px/50px "" } .on3 { font: