内容简介:
- 反射的概念
- 使用反射操作类成员的前提
- 反射在实际开发中的应用
- Class对象的三种获取方式
- Class类常用方法
- 反射之操作构造方法
- 反射之操作成员方法
- 反射之操作成员变量
- 反射操作的Student实体类代码
反射的概念:
- 反射是一种机制,利用该机制可以在程序的运行过程中对类进行解剖并操作类中的所有成员: 构造方法,成员变量,成员方法等。
使用反射操作类成员的前提:
反射在实际开发中的应用:
- 开发IDE(集成开发环境,比如Eclipse,IDEA…)
- 各种框架的设计,比如Hibernate,Spring,Struct 简称:SSH
Class对象的三种获取方式:
/**
获得Class对象的三种方式
* 方式1:通过对象名调用getClass方法获得
* 方式2:直接通过类名.class获得
* 方法3:通过Class类的静态方法获得:static Class forName("类全名字符串");
以上三种方式获得的Class对象都是相同的。
*/
public class ReflectDemo01 {
public static void main(String[] args) throws ClassNotFoundException {
String str = "HelloWorld";
Class c1= str.getClass();
Class c2 = String.class;
Class c3 = Class.forName("java.lang.String");
System.out.println(c1 == c2);
System.out.println(c1 == c3);
System.out.println(c2 == c3);
}
}
Class类常用方法:
/**
Class类常用方法
String getSimpleName(); 获得类名字符串
String getName(); 获得类全名字符串
T newInstance() ; 创建对象,类必须有public修饰的无参数构造方法。
*/
public class ReflectDemo02 {
public static void main(String[] args) throws Exception, InstantiationException {
Class<Student> c = Student.class;
System.out.println(c.getSimpleName());
System.out.println(c.getName());
Student stu = c.newInstance();
System.out.println(stu);
}
}
反射之操作构造方法:
/**
构造方法概述
* 每一个类中的构造方法都是一个Constructor类的对象。
* 获得构造方法对象的目的就是要利用构造方法对象创建对象。
Class类中与Method相关的方法
1. Constructor getConstructor(Class... parameterTypes)
* 根据指定参数类型获得对应的构造方法对象,只能获得public修饰的方法
2. Constructor getDeclaredConstructor(Class... parameterTypes)
* 根据指定参数类型获得对应的构造方法对象,包括private修饰
3. Constructor[] getConstructors()
* 获得所有的构造方法对象,只能获得public修饰的
4. Constructor[] getDeclaredConstructors()
* 获得所有的构造方法对象,包括private修饰的
Constructor类成员方法
* T newInstance(Object... initargs)
* 根据指定参数来创建对象
* void setAccessible(true)
* 设置是否取消权限检查,true表示取消,false表示不取消。
* 暴力反射
*/
public class ReflectDemo03 {
@Test
public void test03()throws Exception{
Class c = Class.forName("com.itheima._03反射.Student");
Constructor[] cons = c.getDeclaredConstructors();
for (Constructor con : cons) {
System.out.println(con);
}
}
@Test
public void test02() throws Exception {
Class c = Class.forName("com.itheima._03反射.Student");
Constructor con = c.getDeclaredConstructor(String.class);
con.setAccessible(true);
Object stu = con.newInstance("rose");
System.out.println(stu);
}
@Test
public void test01() throws Exception {
Class c = Class.forName("com.itheima._03反射.Student");
Constructor con = c.getConstructor(String.class,int.class);
System.out.println(con);
Student stu = (Student) con.newInstance("jack",20);
System.out.println(stu);
Constructor con02 = c.getConstructor();
Student stu02 = (Student) con02.newInstance();
System.out.println(stu02);
}
}
反射之操作成员方法:
/**
成员方法概述
* 每一个类中的成员方法都是一个Method类的对象。
* 获得Method对象的目的就是要调用该方法
Class类中与Method相关的方法
* Method getMethod(String methodName, Class...args)
* 根据方法名和参数类型获得对应的Method对象,只能获得public修饰的
* Method getDeclaredMethod(String methodName, Class...args)
* 根据方法名和参数类型获得对应的Method对象,包括private修饰的
* Method[] getMethods()
* 获得类中的所有的成员方法对象,只能获得public的,包括父类的
* Method[] getDeclaredMethods()
* 获得类中的所有的成员方法对象,只能获得本类的,包括private
Method类成员方法
* Object invoke(Object obj, Object... args)
* 调用obj对象的该方法,args:调用方法传递的参数
* 返回值是Object
2. void setAccessible(boolean flag)
* 设置是否取消权限检查,true表示取消,false表示不取消。
* 暴力反射
*/
public class ReflectDemo04 {
@Test
public void test04() throws Exception {
Class c = Class.forName("com.itheima._03反射.Student");
Method[] methods = c.getDeclaredMethods();
for (Method m:methods) {
System.out.println(m);
}
}
@Test
public void test03() throws Exception {
Class c = Class.forName("com.itheima._03反射.Student");
Object stu = c.newInstance();
Method studyMethod = c.getDeclaredMethod("study",int.class);
studyMethod.setAccessible(true);
studyMethod.invoke(stu,20);
}
@Test
public void test02() throws Exception {
Class c = Class.forName("com.itheima._03反射.Student");
Method eatMethod = c.getMethod("eat",String.class);
eatMethod.invoke(null,"蛋蛋");
}
@Test
public void test01() throws Exception {
Class c = Class.forName("com.itheima._03反射.Student");
Object stu = c.newInstance();
Method studyMethod = c.getMethod("study");
studyMethod.invoke(stu);
}
}
反射之操作成员变量:
/**
成员变量概述
* 每一个成员变量都是一个Field类的对象,通过Field对象可以给成员变量赋值和取值。
Class类与Field相关的方法
* Field getField(String name);
* Field getDeclaredField(String name);
* Field[] getFields();
* Field[] getDeclaredFields();
Field类成员方法
void set(Object obj, Object value)
void setInt(Object obj, int i)
void setLong(Object obj, long l)
void setBoolean(Object obj, boolean z)
void setDouble(Object obj, double d)
Object get(Object obj)
int getInt(Object obj)
long getLong(Object obj)
boolean getBoolean(Object ob)
double getDouble(Object obj)
void setAccessible(true);暴力反射,设置为可以直接访问私有类型的属性。
Class getType(); 获取属性的类型,返回Class对象。
*/
public class ReflectDemo05 {
@Test
public void test04() throws Exception {
Class c = Student.class;
Field[] fs = c.getDeclaredFields();
for (Field f:fs) {
System.out.println(f);
}
}
@Test
public void test03() throws Exception {
Class c = Student.class;
Field f = c.getDeclaredField("address");
f.setAccessible(true);
f.set(null,"东莞");
System.out.println(f.get(null));
}
@Test
public void test02() throws Exception {
Class c = Student.class;
Object stu = c.newInstance();
Field f = c.getDeclaredField("name");
f.setAccessible(true);
f.set(stu,"jack");
System.out.println(stu);
}
@Test
public void test01() throws Exception {
Class c = Student.class;
Object stu = c.newInstance();
Field f = c.getField("gender");
f.set(stu,"男");
Field ageField = c.getField("age");
ageField.set(stu,"30");
Object gender = f.get(stu);
System.out.println(gender);
System.out.println(ageField.get(stu));
}
}
Student实体类代码:
public class Student {
private static String address;
public String gender;
private String name;
public Integer age;
public Student(String name, int age) {
System.out.println("两个参数的构造方法");
this.name = name;
this.age = age;
}
public Student() {
System.out.println("无参数构造方法");
}
private Student(String name){
System.out.println("一个参数构造方法");
this.name = name;
}
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;
}
public void study(){
System.out.println("好好学习,天天向上");
}
private void study(int hour){
System.out.println("好好学习,天天向上 = " + hour);
}
public static void eat(){
System.out.println("好好吃,好好睡");
}
public static void eat(String name){
System.out.println("好好吃,好好睡 " + name);
}
@Override
public String toString() {
return "Student{" +
"gender='" + gender + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}