java反射机制 路径_Java反射机制

.反射的概述

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

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

反射是java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法

.反射强大之处:

反射机制它没有局限性,可以知道任意一个类的所有属性以及方法,对于任意一个对象,都能够调用它的任意一个方法和属性。

例:

* 为什么jdbc连接要使用Class.forName("com.jdbc.mysql.Driver");*不管是mysql的驱动 Driver还是Oracle的驱动或者其他驱动;

* 它都需要去实现jdbc的一个驱动接口;* com.jdbc.mysql.Driver extendsjava.sql.Driver* java.sql.Driver d= Class.forName("com.jdbc.mysql.Driver")*

*例:*

* xxx

* com.xxx.xxxServlet

*

*...* com.xxx.xxxServlet extendshttpServlet*通过建模我们就可以获取到com.xxx.xxxServlet这个路径* Class> clz=Class.forName("com.xxx.xxxServlet");* httpServlet httpservlet = clz.newInstanse();//获取到类对象就什么都可以干了

一切反射相关的代码都从获得类(java.lang.Class)对象开始

1 Class.forName(完整类名)              jdbc、自定义mvc框架用到

2 类名.class                                     可用作通用的查询

3 对象.getClass()                             通用增删改可用

注1:ClassNotFoundException(类名错|少jar包)

注2:同一类的、类对象只会创建一个

测试类信息:

packagecom.yuan.reflect;public classStudent {privateString sid;privateString sname;publicInteger age;static{

System.out.println("加载进jvm中!");

}publicStudent() {super();

System.out.println("调用无参构造方法创建了一个学生对象");

}publicStudent(String sid) {super();this.sid =sid;

System.out.println("调用带一个参数的构造方法创建了一个学生对象");

}publicStudent(String sid, String sname) {super();this.sid =sid;this.sname =sname;

System.out.println("调用两个参数的构造方法创建了一个学生对象");

}

@SuppressWarnings("unused")privateStudent(Integer age) {

System.out.println("调用Student类私有的构造方法创建了一个学生对象");this.age =age;

}publicString getSid() {returnsid;

}public voidsetSid(String sid) {this.sid =sid;

}publicString getSname() {returnsname;

}public voidsetSname(String sname) {this.sname =sname;

}public voidhello() {

System.out.println("你好!我是" + this.sname);

}public voidhello(String name) {

System.out.println(name+ "你好!我是" + this.sname);

}

@SuppressWarnings("unused")privateInteger add(Integer a, Integer b) {return new Integer(a.intValue() +b.intValue());

}

@OverridepublicString toString() {return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";

}

}

1、Class.forName("类的全路径名");

Class clz = Class.forName("com.yuan.reflect.Student");

System.out.println(clz);

结果:

class com.yuan.reflect.Student

2、类名.class

Class clz=Student.class;

System.out.println(clz);

结果:

class com.yuan.reflect.Student

3、类(Class类类的类对象) 实例.getClass()      通用增删改可用

Student stu=newStudent();

Class clz=stu.getClass();

System.out.println(clz);

结果:

class com.yuan.reflect.Student

.反射的三大作用

1. 实例化对象          .newInstance();

代码:

packagecom.yuan.reflect;importjava.lang.reflect.Constructor;/*** 反射实例化

* 1.能够实例化未知的类

* 2.能够通过私有的构造器创建实例

*@author***

**/

public classDemo2 {public static void main(String[] args) throwsException {

Class clz= Student.class;//1、反射调用无参构造方法创建了一个学生对象

// Student stu=(Student)clz.newInstance();//2、调用一个有参构造方法创建一个学生对象//拿到构造器类//Constructor con = clz.getConstructor(String.class);//返回一个构造器// //通过构造器实例化对象//Student stu = (Student)con.newInstance("s007");//System.out.println(stu);//3、调用两个有参构造方法创建一个学生对象//拿到构造器类//Constructor con = clz.getConstructor(String.class,String.class);//返回一个构造器// //通过构造器实例化对象//Student stu = (Student)con.newInstance("s007","zhangsna");//System.out.println(stu);//4、调用Student类私有的构造方法创建了一个学生对象//#java.lang.NoSuchMethodException: 未找到该方法(因为方法私有化所以不可被调用)//# getConstructor 这个方法只能寻找到public(公开的)修饰的构造器//Constructor con = clz.getConstructor(Integer.class);//# getDeclaredConstructor 此方法可以寻找到任何修饰符修饰的构造器//Constructor con = clz.getDeclaredConstructor(Integer.class);//# 设置私有方法可被访问//con.setAccessible(true);// //通过构造器实例化对象//Student stu = (Student)con.newInstance(17);//System.out.println(stu);

}

}

结果1:

65cdaf6a1f14fe6fed4eb36e2014a429.png

结果2:

1dff39ca8a7e0192aba7746884fa5972.png

结果3:

c181da5b1bdf72ee8e9f04f06dc832b2.png

结果4:

913ae82beadbe225a52a7aa2872ddfa3.png

出现错误1:java.lang.NoSuchMethodException ,说明你用的是getConstructor()方法,换成getDeclaredConstructor();

出现错误2: java.lang.IllegalAccessException    没有设置私有可访问,加 .setAccessible(true);

这两种都是针对于获取私有方法时找不到方法会出现的错误

2. 动态调用方法      .invoke

public static void main(String[] args) throwsException {

Student stu=newStudent();//stu.hello();//普通调用方法

Class clz=stu.getClass();//调用无参方法//Method m = clz.getDeclaredMethod("hello");//m.invoke(stu);//调用带参方法

Method m = clz.getDeclaredMethod("add",Integer.class,Integer.class);

m.setAccessible(true);//invoke 如果反射动态调用的方法是被void所修饰,他返回的就是null//如果反射动态调用的方法不是被void所修饰,那么返回的就是被调用的方法的返回值

Object o=m.invoke(stu,20,5);

System.out.println(o);

}

结果:

3d0fb87c1ab4c395242fc78486a2b762.png

3 .读写属性             set/get

packagecom.yuan.reflect;importjava.lang.reflect.Field;/*** 反射属性赋值取值

*

* 反射能将jsp传递过来的参数直接封装到实体类中

*

*@author***

**/

public classDemo4 {public static void main(String[] args) throwsException{

Student stu=new Student("s008","lili");//stu.setSid("s004");

stu.age=22;//System.out.println(stu);

// 赋值//反射处理的是一类的问题,在处理多个属性赋值或取值的时候,使用反射可以减省很多代码//处理私有(private)属性时 需要设置它为可被访问: setAccessible(true);

Class clz=stu.getClass();

Field field= clz.getDeclaredField("sid");//被赋值的属性

field.setAccessible(true);//设置私有可被访问

field.set(stu, "s02");//属性赋值

System.out.println(stu);

System.out.println(field.get(stu));

//取值//Field[] fields = clz.getDeclaredFields();//for (Field field : fields) {//field.setAccessible(true);//System.out.println(field.getName()+"--"+field.get(stu));//}

}

}

赋值结果:

加载进jvm中!

调用两个参数的构造方法创建了一个学生对象

Student [sid=s02, sname=lili, age=22]

s02

取值结果:

加载进jvm中!

调用两个参数的构造方法创建了一个学生对象

sid--s008

sname--lili

age--22

.访问修饰符    getModifiers()

测试类信息:

public classStudent {privateString sid;privateString sname;publicInteger age;

}

测试代码:

public static voidmain(String[] args) {

Class clz=Student.class;

Field[] fields=clz.getDeclaredFields();for(Field field : fields) {

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

System.out.println(Modifier.toString(field.getModifiers()));

}

}

输出结果:

-->private

-->private

-->public

谢谢观看!^-^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值