反射机制学习记录

一、反射

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

二、Java反射机制提供的功能

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

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

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

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

生成动态代理。

三、反射相关的API

java.lang.Class 代表一个类

java.lang.reflect.Method 代表类的方法

java.lang.reflect.Field 代表类的成员变量

java.lang.reflect.Constructor 代表类的构造方法

……

四、简单示例

public class Person {
    private String name;
    private int age;

    public Person() {
    }

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

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void show(){
        System.out.println("我是一个人");
    }

    public void display(String nation){
        System.out.println("我的国籍是"+nation);
    }

    @Override
    public String toString() {
        return "Person[name="+name+",age="+age;
    }
}

import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;

public class TestReflection {

    //在有反射以前创建一个类的对象,并且调用其中的方法和属性
    @Test
    public void test1(){
        Person person=new Person();
        person.setAge(10);
        person.setName("小明");
        System.out.println(person);
        person.show();
        person.display("中国");
    }

    //通过反射以前创建一个类的对象,并且调用其中的结构
    @Test
    public void test2() throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        Class<Person> clazz=Person.class;
        //创建clazz对应的运行时类Person类的对象
        Person person=clazz.newInstance();
        System.out.println(person);
        Field f1=clazz.getField("name");
        f1.set(person,"韩梅梅");
        System.out.println(person);
    }
}

可能运行test2()的时候回抛出如下异常:

没有“name”这个属性存在。出现这个异常的原因可能是对应字段不存在,或者对应的属性设置为私有,而私有的属性,反射也是无法获取的,改为public就可以。

修改以后的现象就是:

这就是通过反射调用运行时类的指定属性,可以调用公有也可以调用私有的属性,以及调用指定的方法:

//调用公有的属性Field f1=clazz.getField("name");f1.set(person,"韩梅梅");
System.out.println(person);
//调用私有的属性,getDeclaredField调用声明过的属性,
// setAccessible设置访问权限
Field f2=clazz.getDeclaredField("age");
f2.setAccessible(true);
f2.set(person,20);
System.out.println(person);
//通过反射调用运行时类的指定方法
Method method1=clazz.getMethod("show");
method1.invoke(person);
Method method2=clazz.getMethod("display", String.class);//加上方法参数类型
method2.invoke(person,"中国中国");

1、Class类

首先了解Class类,它是反射的源头,

所有类都从Object类中继承了getClass()方法,它会返回一个Class类,即某个特定对象的运行时类。

产生对象的方式通常有两种:

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

反射方式:实例化对象——>getclass()方法——>得到完整的“包类”名称

简而言之:反射,即通过对象反射求出类的名称,从包类实例化,再反过来,再从实例获得运行时类,再由运行时类找倒其中的结构。某个对象对着镜子可以得到自己的属性、方法、构造器以及实现的接口等等信息。

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

 @Test
 public void test3(){
        Person person=new Person();
        //通过运行时类对象的getClass(),返回其运行时类
        Class clazz=person.getClass();
        System.out.println(clazz);
 }

输出结果:

我们创建一个类,通过编译(javac.exe),生成对应的.class文件,

之后加载(java.exe,通过JVM的类加载器来完成)此.class文件,

此.class文件加载到内存以后,就是一个运行时类,存放在缓存区,那么这个运行时类本身就是一个Class实例。

每一个运行时类只加载一次。

原文地址:https://www.cnblogs.com/chen-ying/p/11074578.html

时间: 2024-10-10 10:45:23

反射机制学习记录的相关文章

JAVA反射机制—学习总结

最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象. 什么是反射机制? "JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制."我们通过一些例子,更好理解反射机制.Class类 我们知道Java是一门面向对象

JAVA的反射机制学习笔记(二)

上次写JAVA的反射机制学习笔记(一)的时候,还是7月22号,这些天就瞎忙活了,自己的步伐完全被打乱了~不能继续被动下去,得重新找到自己的节奏. 4.获取类的Constructor 通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例 Class<T>类提供了几个方法获取类的构造器. public Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,它反

C#反射机制学习总结 .

反射的定义:审查元数据并收集关于它的类型信息的能力.元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等. System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码,如下所示: [csharp] view plaincopyprint? System.Reflection.Assembly System.Reflection.MemberInfo System.Reflectio

java反射机制学习小结

之前一直对java的反射机制理解得很模糊,今天因为学习spring,所以花了些时间总算把它理顺了,记录一下 另外,推荐读读这篇文章,写的挺好的http://blog.csdn.net/woshixuye/article/details/7700455 class Person { private String name; private int age; // public Person(String name,int age){ // this.name=name; // this.age=a

java反射机制学习:初始反射机制

本人小白一枚,想和大家一起分享我学习java的笔记和心得. 反射机制: 指的是可以于运行时加载.探知.使用编译期间完全未知的类. 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: Class clazz = Class.forName(com.danchel.reflect.User); 加载完类之后,在堆内存中,就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象

黑马程序员---Java反射机制学习

由现在这个时间补上反射机制的学习笔记,本想报20期的JavaEE班,无奈真担心自己过不去,所以这段时间,一直的复习现在改报21期的吧!! 准备知识:一 1.Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method:    其中class代表的时类对象,    Constructor-类的构造器对象,    Field-类的属性对象,    Method-类的方法对象. 2.在Java中,每个class都有一个相应的Class对象.也就是说,当我们编写一

Thinking in Java---类型信息和java反射机制学习笔记

前面学习的多态给了我们一个很好的承诺:我们编写的代码只要与基类打交道,而不用为每一个新增加的子类写一份代码.但是这种思想在我们想要访问子类自己定义的方法时,就会有问题了.如下面的代码所示: class Base1{ void f(){ System.out.println("Base.f()"); } } class Sub extends Base1{ void f(){ System.out.println("Sub.f()"); } void g(){ Sys

php反射机制学习

PHP 5 具有完整的反射 API,可以通过反射机制来获取类,接口,函数的详细信息.例如可以通过反射api的成员属性,成员方法,命名空间的名称,检测某个类是否为抽象类等操作.(欢迎指点) 一般用途是在框架中配合自动加载类来完成 对类的实例化操作. 1.建立一个Person类的反射类,然后实例化此类. <?php class Person { /** * demo */ private $_allowDynamicAttributes = false; /** demo*/ public $id

JAVA反射机制学习随笔

JAVA反射机制是用于在运行时动态的获取类的信息或者方法,属性,也可以用来动态的生成类,由于所有类都是CLASS的子类,我们可以用一个CLASS类的实例来实例化各种类 例如: Class<?> class1 = null; Class<?> class2 = null; //写法1, 可能抛出 ClassNotFoundException [多用这个写法] class1 = Class.forName("cn.lee.demo.Person"); System.