java中对反射是怎么理解的_浅谈java中的反射

引言:java的高级特性-反射一直是困扰自己的一个很大问题,今天专门花了半天再将java中的反射看了一遍,下面简单谈谈自己对反射的理解,以及它的具体用法:

一:什么是反射?

在java核心编程中是这样定义的:能够分析类能力的程序;

public class fruit{

private String name;

public fruit(String name){

this.name = name;

}

public void getName(){

return name;

}

public String setName(String name){

this.name = name;

}

public static void main(String[] args){

fruit apple =new fruit();

apple.getName();

}

}

按照Java创建对象的正常逻辑,如上面的代码所示,我们一般都是根据具体的类fruit来创建对象apple,然后在利用我们所创建的对象去调用方法;apple.getName();而java中的反射的流程则相反是根据具体的对象去获取相关的类Class的信息,

二:反射的作用:

<1>:可以在程序运行过程中分析类的能力

<2>:在运行中查看对象,例如编写一个toString方法供所有类使用

<3>:实现数组的操作代码

<4>:利用Method对象;

三:具体怎么使用:

补充知识:我们都知道,编写java程序时我们所编写的文件是一个名为xxx.java的文件,通过java编译器编译之后会成为一个.class文件;这时再通过JVM的类加载器加载到JVM的运行时数据区里面的方法区(.class)文件,所谓方法区里面保存的类的相关信息就是指这一过程的产生的class对象;

java程序在运行过程中会为每一对象保存一个Class对象,用来保存该对象和类的一些相关信息;比如:方法,属性,构造函数等;所以想要使用反射我们首先要做的就是拿到Class对象;

<1>:拿到Class对象:

有三种方法:

A:根据对象获取的getClass()方法:

Class cls = apple.getClass();

B:根据类的class属性获取

Class cls = fruit.class;

C:根据Class类的静态方法forName("类的完整路径")

Class cls = Class.forName("Chapter1.fruit")

具体采用那一种,大家可以根据具体情况具体分析;

<2>:根据拿到的Class对象创建我们所需的对象:

fruit orange = (fruit)cls.newInstance();//注意该方法返回的Object对

象,所以我们需要强制类型转换;

这里创建对象调用的是fruit类中的默认的构造方法,如果没有默认构造方法此项操作将会报错已检查异常(即运行时会报错);

所以我们调用此方法时一定要保证目标类有默认的构造方法;

<3>:获取调用构造方法:

Constructor con = cls.getConstructor(Class>... parameterTypes)//返回指定采参数类型的构造方法;注意参数一定要传递Class对象哦!

Constructor[] con = cls.getConstructors();//返回所有的共有构造器:构造方法数组;

Constructor[] con = cls.getDeclaredConstructors();//返回所有的构造器:构造方法数组;

Constructor con = cls.getDeclaredConstructor(Class>... parameterTypes);//返回指定的构造器:构造方法数组;

//在拿到对应的都早方法之后我们就可以根据指定构造方法创建对象

Constructor cons = cls.getConstructor(String.class);

fruit f = cons.newInstance("陈鹏");

<4>:获得调用普通方法

Method[] methods = cls.getMethods();//返回该类中以及其超类中所有的的公有的方法

Method[] methods = cls.getDeclaredMethods();//返回该类中所有的的公有的方法,不包括从超类中继承而来的方法

Method method = cls.getMethod(String name, Class>... parameterTypes)//返回指定的方法这里的name是方法名,parameterTypes表示参数列表

Method method = cls.getMethod("getName",String.class);

method.invoke(Object obj, Object... args);//这里的obj表示的调用该方法的对象,后面的args是参数列表;

关于invoke方法:第一个参数是隐式参数(this)第二个参数是显示参数,(java SE 5.0之前)必须传递一个数组对象,如果没有显示参数可以将传递一个null;如果是静态方法可以将第一参数忽略即将其设置为null;

<5>:访问域(属性)

Field field = cls.getFiled(String name);//返回声明在该类或其其超类中的指定的共有域

Field[] fields = cls.getFileds();//返回所有的声明在该类以及其超类中的共有域

Field field = cls.getDeclaredFiled(String name);//返回所有的声明在该类中的共有域;

Field[] fields = cls.getDeclaredFileds();//返回所有的声明在该类中的共有域;

Field field = cls.getDeclaredField("name");

ps一般情况下我们的私有属性是不可以进行访问,但java的反射也可以让我们访问到私有属性:

//通过调用下面方法表可将私有属性设置为可以访问的

Field.setAccessable(true)

补充例子1:使用Java的反射获取泛型信息:

class Person{

public Person(){

//Type[] cls = ((ParameterizedType)(this.getClass().getGenericSuperclass())).getActualTypeArguments();

//获取父类的子类传递过来的类型

Type type= this.getClass().getGenericSuperclass();

//转换成对应的参数类型

ParameterizedType rtype =(ParameterizedType)type;

Type[] types = rtype.getActualTypeArguments();

for(Type t:types){

System.out.println(((Class)t).getName());

}

}

}

class Student extends Person{

public Student(){

System.out.println("我是子类的构造方法!");

}

}

这里注意:调用子类构造器之前会先调用父类的构造器;

补充例子2:使用反射回去注解信息:

反射注解

要求

注解的保留策略必须是RUNTIME(有三种状态:RESOURCE,CLASS,RUNTIME)

反射注解需要从作用目标上返回

类上的注解,需要使用Class来获取

方法上的注解,需要Method来获取

构造器上的注解,需要Construcator来获取

成员上的,需要使用Field来获取

Class

Method、Constructor、Field:这三个类都实现了:AccessibleObject类

它们都有一个方法:

Annotation getAnnotation(Class),返回目标上指定类型的注解!

Annotation[] getAnnotations(),返回目标上所有注解!

总结:以上就是自己关于java反射方面的简单的理解,如果内容有出错的地方望大家及时指正,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值