一、反射概念
1.1 对象的反向操作
反射指的是对象的反向操作,根据对象取得对象的来源信息,关注的是对象后面的组成,类,成员,构造等等
- Class是整个类的概念,而这个类的对象的生产模式一共有三种
- 1.Object的getClass()方法,返回的class对象
- 2.类.class,根据具体的类来取得Class类的实例化对象
- 3.forName()方法
- 正常正向:导包-->实例化对象
1.2 反射代码:
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 1.第一种实例化
Date date = new Date();
// class java.util.Date
System.out.println(date.getClass());
// 2.第二种实例化
Class<?> date2 = Date.class;
System.out.println(date2.getName());
// 3.第三种实例化,不需要导包 拿到操作权限
Class<?> date3 = Class.forName("java.util.Date");
System.out.println(date3.getName());
}
}
二、反射的操作
2.1 反射取得父类信息
/**
* @author captain
* @date 2019年5月2日
* 在定义java类的时候,一定要保留一个无参构造方法
* 2.1.取得父类信息
*/
class Person2 {
private int age;
private String name;
public Person2() {}
public Person2(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person2 [age=" + age + ", name=" + name + "]";
}
}
public class ReflectionOperate2 {
public static void main(String[] args) throws Exception{
Class<?> cls = Person2.class;
// 打印构造方法 取得指定参数类型的构造方法
Constructor<?> conts[] = cls.getConstructors();
//Constructor<?> conts = cls.getConstructor(String.class, int.class);
for(int x = 0; x < conts.length; x++) {
System.out.println(conts[x]);
}
// 通过反射调用构造方法,只能调用无参构造方法
System.out.println(cls.newInstance());
}
}
2.2 反射取得普通方法
- 在定义java类的时候,一定要保留一个无参构造方法
- 没有反射,就没有框架,java与其他语言的特别之处,最亮之处
- 取得普通方法 :一定会使用到,解决重复编码 Method的invoke()方法
- 取得一个类的全部方法getMethods() 返回一个method的对象
- 取得指定方法getMethod()
- 所有的方法再有了实例化对象之后才可以使用。有了反射之后,来实现。
- 通过反射来调用setter getter
class Person3 {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class ReflectionOperate3 {
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("com.wang.aliyun.reflect.Person3");
// 拿到所有的方法
Method met[] = cls.getMethods();
for(int x = 0;x <met.length;x ++) {
System.out.println(met[x]);
}
// 任何情况下调用类中的普通方法,必须要有实例化对象
String value = "WANG";
Object obj = cls.newInstance();
Method setMethod = cls.getMethod("setName", String.class);
// 相当于Person.setName()
setMethod.invoke(obj, value);
// 输出的话 相当于Person.getName()
Method getMethod = cls.getMethod("getName");
Object ret = getMethod.invoke(obj);
System.out.println(ret);
}
}
2.3 反射取得成员
- 1.取得成员调用
- 类对象的属性,一定会在实例化之后进行空间的分配,必须保证要有实例化对象 通过反射的newInstance【Object类型】
- 否则属性无法开辟空间
- 2.两组取得属性的方法
- 取得父类中所有的属性 getFields()
- 取得指定类型的属性 getField()
- getDeclaredFields 本类
- getDeclaredField 本类
- 3.开发之中,不会适用如下方法
- 开发使用getter setter方法
class Person4 {
private String name; // 属性
}
class Student extends Person4{
private String school;
}
public class ReflectionOperate4 {
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("com.wang.aliyun.reflect.Person");
{
// 1.普通代码块 取得类全部属性
Field fields[] = cls.getFields();
for(int x = 0; x < fields.length; x ++) {
System.out.println(fields[x]);
}
}
System.out.println("=================================");
{
// 2.普通代码块 取得类全部属性
Field fields[] = cls.getDeclaredFields();
for(int x = 0; x < fields.length; x ++) {
System.out.println(fields[x]);
}
}
System.out.println("=================================");
// 3.指定名字
Object obj = cls.newInstance();
Field nameField = cls.getDeclaredField("name");
System.out.println(nameField.getType().getName()); // java.lang.String
System.out.println(nameField.getType().getSimpleName()); // String
// 取消封装,private的权限不起作用了
nameField.setAccessible(true);
nameField.set(obj, "迪丽热巴");
System.out.println(nameField.get(obj)); //没有setAccessible(true);private权限会报错
}
}
评论