文章目录
前言
提示:反射机制在基础知识的学习中属于比较重要的部分,学好反射有助于后期第三阶段的学习。这也是我一直想要学好的一个阶段,无论如何需要抓紧它。
提示:以下是本篇文章正文内容,下面案例可供参考
一、反射是什么?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、获取字节码文件的三个方式
本次需要用到一个学生类作为实验对象(Student.java)
创建学生类
public class Student {
public String name;
private char sex;
private int age;
private String classId;
private String id;
public Student() {
}
public Student(String classId, String id) {
this.classId = classId;
this.id = id;
}
public Student(String name, char sex, int age, String classId, String id) {
this.name = name;
this.sex = sex;
this.age = age;
this.classId = classId;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void eat() {
System.out.println(this.name + "吃饭饭");
sleep();
}
private void sleep() {
System.out.println(this.name + "睡觉觉");
}
@Override
public String toString() {
return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;
}
}
创建一个properties文件【classpath.properties】
创建Test01类 ,通过三种方式来获取字节码文件,此处推荐第三种方式,理由是它的可变性要好很多
import java.util.Properties;
public class Test01 {
public static void main(String[] args) throws Exception{
Class<?> c1=Student.class;
Student stu=new Student();
Class<?> c2 = stu.getClass();
Properties p=new Properties();
p.load(Test01.class.getClassLoader().getResourceAsStream("classpath.properties"));
String classPath = p.getProperty("classPath");
Class<?> c3 = Class.forName(classPath);
}
}
三、通过反射来操作类
(1)通过反射来获取类的构造方法
这一个案例中 我们仍然以Student来作为实验对象
Student 类代码
package com.yzy.Reflex.TestReflex01;
public class Student {
public String name;
private char sex;
private int age;
private String classId;
private String id;
public Student() {
}
public Student(String classId, String id) {
this.classId = classId;
this.id = id;
}
public Student(String name, char sex, int age, String classId, String id) {
this.name = name;
this.sex = sex;
this.age = age;
this.classId = classId;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void eat() {
System.out.println(this.name + "吃饭饭");
sleep();
}
private void sleep() {
System.out.println(this.name + "睡觉觉");
}
@Override
public String toString() {
return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;
}
}
创建一个测试类Test02
import java.lang.reflect.Constructor;
import java.util.Properties;
public class Test02 {
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.load(Test02.class.getClassLoader().getResourceAsStream("classpath.properties"));
String classPath = p.getProperty("classPath");
Class<?> c = Class.forName(classPath);
Constructor<?> constructor=c.getDeclaredConstructor(String.class,char.class,int.class,String.class,String.class);
constructor.setAccessible(true);
Student student= (Student)constructor.newInstance("雍仲杨",'男',21,"2107","001");
System.out.println(student);
}
}
(2)通过反射机制来操作属性
仍然使用之前的Student作为实验对象
Student对象
public class Student {
public String name;
private char sex;
private int age;
private String classId;
private String id;
public Student() {
}
public Student(String classId, String id) {
this.classId = classId;
this.id = id;
}
public Student(String name, char sex, int age, String classId, String id) {
this.name = name;
this.sex = sex;
this.age = age;
this.classId = classId;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void eat() {
System.out.println(this.name + "吃饭饭");
sleep();
}
private void sleep() {
System.out.println(this.name + "睡觉觉");
}
@Override
public String toString() {
return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;
}
}
import java.lang.reflect.Field;
import java.util.Properties;
public class Test03 {
public static void main(String[] args) throws Exception {
Properties p=new Properties();
p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties"));
String classPath = p.getProperty("classPath");
Class<?> c = Class.forName(classPath);
Student student=new Student("唐坤梅",'女',21,"2107","002");
Field nameField = c.getField("name");
nameField.set(student,"廖薇");
Field age = c.getDeclaredField("age");
age.setAccessible(true);
age.set(student,22);
System.out.println(student);
}
}
(3)利用反射机制来操作方法
老规矩使用Student作为实验对象
public class Student {
public String name;
private char sex;
private int age;
private String classId;
private String id;
public Student() {
}
public Student(String classId, String id) {
this.classId = classId;
this.id = id;
}
public Student(String name, char sex, int age, String classId, String id) {
this.name = name;
this.sex = sex;
this.age = age;
this.classId = classId;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void eat() {
System.out.println(this.name + "吃饭饭");
sleep();
}
private void sleep() {
System.out.println(this.name + "睡觉觉");
}
@Override
public String toString() {
return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;
}
}
import java.lang.reflect.Method;
import java.util.Properties;
public class Test04 {
public static void main(String[] args) throws Exception {
Properties p=new Properties();
p.load(Test04.class.getClassLoader().getResourceAsStream("classpath.properties"));
String classPath = p.getProperty("classPath");
Class<?> c = Class.forName(classPath);
Student student=new Student("雍仲杨",'男',22,"2107","003");
Method setAge = c.getMethod("setAge", int.class);
setAge.invoke(student,22);
Method sleep = c.getDeclaredMethod("sleep");
sleep.setAccessible(true);
sleep.invoke(student);
System.out.println(student);
}
}
(4)利用反射操作数组
import java.lang.reflect.Array;
public class Test05 {
public static void main(String[] args) throws Exception {
String [] ss = (String[]) Array.newInstance(String.class, 5);
System.out.println("利用反射获取数组的长度:"+Array.getLength(ss));
Array.set(ss, 0, "盖伦");
Array.set(ss, 1, "赵信");
Array.set(ss, 2, "嘉文");
Array.set(ss, 3, "泰隆");
Array.set(ss, 4, "李青");
for (int i=0;i<Array.getLength(ss);i++){
System.out.println(Array.get(ss,i));
}
}
}
难点:使用反射操纵泛型
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
public class Test06 {
public static void main(String[] args) throws Exception{
Class<?> c=Class.forName("com.yzy.Reflex.TestReflex01.Test06");
Method method01 = c.getDeclaredMethod("method01", ArrayList.class, HashMap.class);
method01.setAccessible(true);
Type[] genericParameterTypes = method01.getGenericParameterTypes();
for (Type type:genericParameterTypes) {
ParameterizedType parameterizedType=(ParameterizedType)type;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
for (Type acTypeArguments:actualTypeArguments) {
System.out.println(acTypeArguments);
}
}
System.out.println("----------------------------------------------------------");
Method method02 = c.getDeclaredMethod("method02");
method02.setAccessible(true);
Type genericReturnType = method02.getGenericReturnType();
ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
for (Type type:actualTypeArguments) {
System.out.println(type);
}
}
public static void method01(ArrayList<String> list, HashMap<String,Integer> map){
}
public static HashMap<String,Integer>method02(){
return null;
}
}
总结
以上就是今天要讲的内容,本文仅仅简单介绍了Java基础中的反射机制的使用,而反射机制在后期的学习中提供了大量能使我们快速便捷地处理数据的函数和方法。尤其是在第三阶段的学习中。
|