Java反射Reflect的使用详解

一. 什么是反射

在运行状态中,对于任意一个类,都能够知道其所有属性和方法,对于任意一个对象,都能够调用其任意方法和属性,这种动态获取信息、动态调用方法的能力称为Java语言的反射机制,大部分框架都有用到反射机制,了解反射的使用方法非常重要。

一个类通常包含了属性、方法、构造函数等,而Java一般情况下是现有类再有对象,通过对象调用各种属性和方法,而Java反射则是通过已有的对象,反过来得到其所属类的相关信息,调用所属类的相关方法。

二. 反射的基础Class 2.1 Class类概述

我们知道在Java的世界中,万事万物皆对象。其实类本身也是对象,任何一个类都是Class类的实例对象。

//定义了一个SuperHero的类 public class SuperHero {}

如上面定义的SuperHero类,是类也是对象,

对象:SuperHero类是Class类的实例,Class类是SuperHero的类类型,故而为对象;

类:以类的方式创建,SuperHero本身可以调用SuperHero ironMan = new SuperHero ()被实例化,ironMan 就是创建的实体,故而也是类。

Java反射Reflect的使用详解

Class类很特殊,它表示了某个类的类类型,被不可被继承,每个类的Class对象仅有一个,Class类没有公共构造函数。 相反, Class对象由Java虚拟机自动构建,因为加载了类,并且通过调用类加载器中的defineClass方法,原始Java类型( boolean , byte , char , short , int , long , float和double ),和关键字void也表示为Class对象

//Class源码,final修饰不可被继承,构造函数是private的,不可手动实例化 public final class Class<T> { private Class(ClassLoader loader) { // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. classLoader = loader; } } public static void main(String[] args) { try { Class clazz1 = Class.forName("java.lang.Integer"); Class clazz2 = Class.forName("java.lang.Integer"); System.out.println(clazz1 == clazz2); System.out.println(int.class); System.out.println(void.class); } catch (ClassNotFoundException e) { e.printStackTrace(); } }

运行结果为:

true int void 2.2 Class类对象获取的三种方式

先定义一个类

package reflectdemo; import java.io.Serializable; /** * 超级英雄类 */ public class SuperHero implements Serializable { public static final String ADDRESS = "earth"; private String id; private String name; private Integer age; private String skill; public SuperHero() { } public SuperHero(String id, String name, Integer age, String skill) { this.id = id; this.name = name; this.age = age; this.skill = skill; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSkill() { return skill; } public void setSkill(String skill) { this.skill = skill; } public void print(){ System.out.println("超级英雄:" + this.name); } } 2.2.1 通过对象获取Class public static void main(String[] args) { SuperHero ironMan = new SuperHero("1","钢铁侠",35, "战甲"); Class clazz = ironMan.getClass(); System.out.println(clazz.getName()); }

输出结果:

reflectdemo.SuperHero 2.2.2 通过类获取Class public static void main(String[] args) { Class clazz = SuperHero.getClass(); System.out.println(clazz.getName()); }

输出结果:

reflectdemo.SuperHero 2.2.3 传入类路径获取Class public static void main(String[] args) { try { Class clazz = Class.forName("reflectdemo.SuperHero"); System.out.println(clazz.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } }

输出结果:

reflectdemo.SuperHero

三种创建方式:

第一种方式对象已经有了,所有的操作直接通过该对象进行即可,

第二种方式需要import将类引入,也不是常用的方式,

第三种仅需传入类的路径,即可得到类的相关信息,是最常用的方式。

2.2.4 获取类信息的常用方法 public static void main(String[] args) { try { Class clazz = Class.forName("reflectdemo.SuperHero"); //获取类名称(含路径) System.out.println(clazz.getName()); //获取类名称(不含路径) System.out.println(clazz.getSimpleName()); //获取所在包 System.out.println(clazz.getPackage()); //通过Class创建对象 SuperHero hero = (SuperHero)clazz.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }

输出结果:

reflectdemo.SuperHero SuperHero package reflectdemo

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/0fcca08088d0daaf191bc2145350ae92.html