Java反射机制

本文深入探讨Java反射机制的概念,包括类、属性、构造方法和方法的获取方式,并通过实例展示反射在创建对象和调用方法上的应用。同时,介绍了反射在构建框架中的作用,以及如何使用反射从配置文件中加载类名并创建对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.反射简述

2.class是什么?

3.通过反射获得field,constructor,method

4.反射的应用

======================华丽丽的分割线======================

1.反射简述

类用于描述一类具有相同属性和方法的东西,那么,java中的类又能否有相应的类去描述?

答案是肯定的,反射(reflect)就是用来把java类中的各种成分映射成各种相应的java类.

java反射涉及的类分别为:field、constructor、method、class。

field 类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。

constructor 类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和 field 类不同,field 类封装了反射类的属性,而 constructor 类则封装了反射类的构造方法。

method 类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法。这个类不难理解,它是用来封装反射类方法的一个类。

class 类:类的实例表示正在运行的 java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 class 对象。

======================华丽丽的分割线======================

2.class是什么?

class:简单而言,就是用来描述java类(与接口)的类.它的实例用来表示正在运行的java应用程序中的类和接口。

如何获得字节码?

class cls = xxx.class;

class cls = xx.getclass();

class.forname(类名);// 返回字节码:若内存中有加载该类,则他找到该类的字节码并返回,若无,则找到该类的路径,加载后返回.

要区别一个概念,这里获得的是类的字节码,与具体的对象无关。

view code

1 public class classtest {

2

3public static void main(string[] args){

4string str1 = "abc";

5string str2 = "123";

6system.out.println("str1.getclass() 等于 str2.getclass()? " + (str1.getclass() == str2.getclass());

7}

8 }

9/* output:

10* str1.getclass()等于str2.getclass()? true

11*/

如前所说,他是用来描述正在运行的java类。这里这里的getclass()获得的是string类型的字节码,故当然相等.

======================华丽丽的分割线======================

3.通过反射获得field,constructor,method

通过反射获得类得各种成分

view code

1 public class reflecttest{

2

3public int a = 47;

4

5private string str = "hello";

6

7public reflecttest(){}

8

9public reflecttest(string str){

10this.str = str;

11}

12

13public string getstr(string str){

14return this.str + "," + str;

15}

16

17public string getstr(){

18return str;

19}

20

21public static void main(string[] args){

22system.out.println("this is genericstest" + args[1]);

23}

24

25 }

这里有一个类,用于待会通过反射来获得它的成分,这个类中有属性(公有与私有,基础类型与非基础类型),两个构造方法,两个方法(多态)。

3.1. 通过反射获得field:

view code

1 import java.lang.reflect.field;

2

3public class reflectfield {

4

5public static void main(string[] args) throws exception {

6class clazz = class.forname("reflecttest");

7system.out.println(clazz.getname());

8

9// method two:

10// class clazz1 = genericstest.class;

11

12// method three:

13// genericstest gt = new genericstest();

14// class clazz2 = gt.getclass();

15

16field fielda = clazz.getfield("a");

17// can not:field fielda = clazz.getfield("str");

18// because str's modifiers is private.

19system.out.println("属性名:" + fielda.getname() + "; 类型:"

20+ fielda.gettype() + "; 权限修饰符:"

21+ fielda.getgenerictype() + "; 值:" + fielda.get(new reflecttest()));

22

23// 既然反射是将类的各种成分映射成相应的类,那么私有的属性理应也可获取(暴力反射):

24reflecttest rt = new reflecttest();

25field fieldstr = clazz.getdeclaredfield("str");

26fieldstr.setaccessible(true);

27system.out.println(fieldstr.get(rt));

28fieldstr.set(rt, "abc");

29system.out.println(fieldstr.get(rt));

30}

31

32 }

在这个类中,演示了如何获得属性,要注意的是,私有属性的获得是需要通过暴力反射。

3.2. 通过反射获得构造方法:

view code

1 import java.lang.reflect.constructor;

2

3

4 public class reflectconstructor {

5

6public static void main(string[] args) throws exception {

7class clazz = class.forname("reflecttest");

8

9// 获取无参的构造方法

10constructorreflecttest> constructor = clazz.getconstructor();

11reflecttest rt = constructor.newinstance();

12system.out.println(rt.getstr());

13

14// 获取有参的构造方法,需指明参数类型

15constructor = clazz.getconstructor(string.class);

16rt = constructor.newinstance("world");

17system.out.println(rt.getstr());

18

19// 可以看出,先通过获取reflecttest的字节码,然后得到它的构造方法,再调用该构造方法生成对象

20// 对于无参的构造方法,class类中提供一个方法可以直接生成该类的对象

21rt = (reflecttest)clazz.newinstance();

22system.out.println(rt.getstr());

23}

24

25 }

3.3. 通过反射获得方法:

view code

1 import java.lang.reflect.method;

2

3

4 public class reflectmethod {

5

6public static void main(string[] args) throws exception{

7reflecttest rt = new reflecttest();

8reflecttest rt2 = new reflecttest();

9method method = reflecttest.class.getmethod("getstr",string.class);

10string message = (string)method.invoke(rt,"world!");

11system.out.println(message);

12}

13 }

要补充的是,对于无参的方法,不用写参数;而对于静态方法时,则为:method.invoke(null,参数名...);

因为静态方法是不需要对象的。。。

======================华丽丽的分割线======================

4.反射的应用

反射的应用:框架。就好比建筑一样,我们先建好框架,等待门窗安进来,而在建房时无需知道门与窗长得什么样。

下面通过一个常用的实例来模拟一个小框架,即通过获取properties文件中的类名,来创建对象(框架的基本原理)

#config.properties

classname=reflecttest

在properties中,由于我做这个实例的时候直接丢到默认包,所以路径就直接写,蛋若有包名,则需写全

view code

1 import java.io.inputstream;

2 import java.util.properties;

3

4

5 public class reflectapp {

6

7public static void main(string[] args) throws exception {

8// 从当前类所对应的包中找到config.properties文件.若在前面加上 "/",则从项目的根目录开始.

9inputstream instream = reflectapp.class.getresourceasstream("config.properties");

10

11// method two:

12// 该方法需从根目录开始,也就是得指明包,这里是默认包,所以直接写

13// inputstream instream = reflectapp.class.getclassloader().getresourceasstream("config.properties");

14properties props = new properties();

15props.load(instream);

16instream.close();

17string classname = props.getproperty("classname");

18system.out.println("创建一个对象: " + class.forname(classname).newinstance());

19}

20

21 }

这就是反射的基本应用,其实在做‘有个饭桶’的时候就用到了,只是当时知其然而不知其所以然。。。现在学框架,懂了这个后回头看,便清晰容易多了。。。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值