黑马程序员技术交流社区
标题: 整理反射部分笔记 [打印本页]
作者: fashionkillyou 时间: 2017-10-30 14:45
标题: 整理反射部分笔记
19.1 反射介绍Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法
对于任意一个对象,都能够调用它的任意一个方法
这种动态获取的以及动态调用对象的方法的功能称为java语言的反射机制
(我理解为就是在运行时,可以去获取当前项目中的所有的.class文件,然后去使用它的方法) 就是在运行时主动的获取对象
19.1.1获取字节码文件的三种方法准备类:
[Java] 纯文本查看 复制代码
public class FuLei {
private String name;
public int age;
private String gender;
public FuLei() {}
private void ss(int a){
System.out.println(a);
}
public FuLei(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
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;
}
@Override
public String toString() {
return "FuLei [name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
public void method(){
System.out.println("我是父类的方法");
}
}
1、通过 对象名.getClass()方法获取
FuLei f = new FuLei();
Class<? extends FuLei> class1 = f.getClass();
2、通过 类名.class属性来获取
System.out.println(FuLei.class);
3、通过 Class.forName(类的全名) ------类的全名是 包名.类名
Class<?> forName = Class.forName("com.test01.FuLei");//为了防止传入错误的类名此处将会抛出异常 ClassNotFoundException
19.1.2 通过获取的构造创建对象字节码对象是什么?如何获取?
newInstance()新实例化对象方法,使用时一定要和获取构造器时的参数保持一致
getConstructor()方法返回的是一个字节码对象,之后的获取方法和属性的方法都是返回的相应的对象
//关于字节码对象,什么是字节码对象?如何获取?
//首先要获取字节码
//这里利用第一种方式获取了字节码文件
Class<?> forName = Class.forName("com.test01.FuLei");
//获取了无参构造,方法一,通过forName.getConstructor()得到无参构造的对象,然后调用无参构造的对象来调用newInstance()方法
// Constructor<?> constructor = forName.getConstructor();
// Object newInstance1 = constructor.newInstance();
//方法二、根据无参构造进行实例化对象 newInstance()新实例化对象,只能创建无参构造来创建对象
Object newInstance = forName.newInstance();
System.out.println(newInstance);
//根据有参构造进行实例化对象
Constructor<?> constructor2 = forName.getConstructor(String.class,int.class);//参数是传的类型的字节码文件
Object newInstance2 = constructor2.newInstance("刘欣明",25);
System.out.println(newInstance2);
19.1.3 反射操作公共成员变量19.1.3.1反射public成员变量注意:这里只能获取被public修饰的成员
通过反射运行public变量流程
1. 通过反射获取该类的字节码对象
Class clazz = Class.forName("com.heima.Person");
2. 创建该类对象
Object p = clazz.newInstance();
3. 获取该类中需要操作的字段(成员变量)
getField(String name) --> 方法传入字段的名称.
注意: 此方法只能获取公共的字段
Field f = clazz.getField("age");
4. 通过字段对象中的方法修改属性值
void set(Object obj, Object value) --> 参数1): 要修改那个对象中的字段, 参数2): 将字段修改为什么值.
f.set(p, 23);
代码演示:
Class<?> forName = Class.forName("com.test01.FuLei");
Object fu = forName.newInstance();
Field age = forName.getField("age");
Field name = forName.getField("name");
name.set(fu, "刘欣明");
age.set(fu, 25);
System.out.println(age);//public int com.test01.FuLei.age
System.out.println(fu);//FuLei [name=刘欣明
Object age2 = age.get(fu);
Object name2 = name.get(fu);
System.out.println(age2);//25
System.out.println(name2);//刘欣明
方法总结:
通过反射获取成员变量并使用
Field[] getFields() --> 返回该类所有(公共)的字段
Field getField(String name) --> 返回指定名称字段
Field[] getDeclaredFields() --> 暴力反射获取所有字段(包括私有)
Field getDeclaredField(String name) --> 暴力反射获取指定名称字段
Field:
Object get(Object obj) --> Field对象调用, 返回传入对象的具体字段
void set(Object obj, Object value) --> Field对象调用
参数1: 要修改的对象
参数2: 将此对象的字段修改为什么值.
19.1.3.2反射private成员变量
反射private属性执行流程
1. 获取学生类字节码对象
2. 获取学生对象
3. 通过getDeclaredField方法获取私有字段
4. 通过setAccessible让jvm不检查权限
5. 通过set方法设置对象为具体的值
Class<?> forName = Class.forName("com.test01.FuLei");//获取字节码文件
Object fu = forName.newInstance();//获取实例对象
Field gender = forName.getDeclaredField("gender");//获取私有的成员变量
gender.setAccessible(true);//暴力反射
gender.set(fu, "男");//设置值
System.out.println(fu);//FuLei [name=null, age=0, gender=男
System.out.println(gender);//private java.lang.String com.test01.FuLei.gender
Object xin = gender.get(fu);
System.out.println(xin);//男
19.1.3.3 反射获取方法执行流程反射public方法执行流程
1. 获取学生类字节码对象
2. 反射手段创建学生对象
3. 调用getMethod方法获取Method对象, 方法形参接受方法的名字
4. 调用Method方法中的invoke()将方法运行
Class<?> Fu = Class.forName("com.test01.FuLei");//字节码文件
Object f = Fu.newInstance();//实例化对象
//无参无返回值
Method method = Fu.getMethod("method");
method.invoke(f);//调用方法
//有参无返回值的方法
Method method2 = Fu.getMethod("setName", String.class);
method2.invoke(f, "lxm");//调用方法
System.out.println(f);
19.2 JavaBean/*
* JavaBean:用于封装数据
* 类使用公共进行修饰
* 提供私有修饰的成员变量
* 为成员变量提供公共getter和setter方法
* 提供公共无参的构造
* 实现序列号接口
*
*/
19.3BeanUtils的常用方法static void setProperty(Object bean, String name, Object value)
static String getProperty(Object bean, String name)
static void populate(Object bean, Map properties)
setProperty 用来给对象中的属性赋值(了解)
参数1: 需要设置属性的对象
参数2: 需要修改的属性名称
参数3: 需要修改的具体元素
getProperty 用来获取对象中的属性(了解)
参数1: 要获取的javaBean对象
参数2: 对象中的哪个属性
Populate 用来给对象中的属性赋值(掌握)
参数1: 要设置属性的对象
参数2: 将属性以Map集合的形式传入
Key : 属性的名称
Value: 属性具体的值
BeanUtils 的setProperty和getProperty方法的底层并不是直接操作成员变量,而是操作成员变量有关的set和get方法
BeanUtils populate(javabean类,map);
//方法setProperty()
public static void setProperty(Object bean, String name,Object value) throws ReflectiveOperationException{
//通过反射获取字节码
Class clazz = bean.getClass();
//获取相应的属性对象
Field f = clazz.getDeclaredField(name);
//设置权限
f.setAccessible(true);
//赋值
f.set(bean, value);
}
//方法getProperty()
public static String getProperty(Object bean, String name) throws ReflectiveOperationException{
//获取字节码对象
Class clazz = bean.getClass();
//获取属性的对象
Field f = clazz.getDeclaredField(name);
f.setAccessible(true);
Object obj = f.get(bean);
return obj.toString();
}
//方法 populate()
public static void populate(Object bean,Map map) throws ReflectiveOperationException{
//根据map里面的键值对的key来获取bean类中的属性,没有属性的话
Class<? extends Object> c = bean.getClass();
Set keys = map.keySet();
for (Object key : keys) {
try{
//根据key获取value
Object value = map.get(key);
//得到属性的对象
Field f = c.getDeclaredField(key.toString());
//设置权限
f.setAccessible(true);
//赋值
f.set(bean, value);
}catch(NoSuchFieldException e){
e.printStackTrace();
}
}
作者: 播妞 时间: 2017-10-30 15:11
快找播妞兑换礼品去qq3414556270
作者: heimalala 时间: 2017-10-30 17:29
受教了
作者: fashionkillyou 时间: 2017-10-30 19:28
播妞 发表于 2017-10-30 15:11 
快找播妞兑换礼品去qq3414556270




啥礼品?
作者: fashionkillyou 时间: 2017-10-30 19:29
heimalala 发表于 2017-10-30 17:29 
受教了
相互学习!好好学习,天天向上!
作者: 丶唯萌Pro 时间: 2017-10-31 22:55
姐姐,你咋这么棒吗?
作者: fashionkillyou 时间: 2017-11-1 00:03
丶唯萌Pro 发表于 2017-10-31 22:55 
姐姐,你咋这么棒吗?
妹妹也很厉害的
作者: battlexing 时间: 2017-11-1 10:10
那么反射到底是个啥呢
作者: fashionkillyou 时间: 2017-11-2 01:23
battlexing 发表于 2017-11-1 10:10 
那么反射到底是个啥呢
就是在运行时获得类和他的对象,可以通过反射获得类的成员属性和方法
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |