反射
参考文章:反射讲解最好的文章
反射--获取Class对象的三种方式
三种方式 | 以及特点 |
---|---|
方式一:类名.class | 最方便的方式 |
方式二:Class.forName() | 最灵活的方式(类的路径) |
方式三:new 类名.getClass() | 最无奈的方式 |
demo:
定义一个学生类(Student)
java
package com.itxs.demo01;
/**
* @Classname : Student
* @Description : TODO 学生类
* @Author : lin_refuel@qq.com
*/
public class Student {
}
三种获取Class方式的验证
java
package com.itxs.demo01;
/**
* @Classname : demo01
* @Description : TODO 反射 - 获取Class对象的方式
* @Author : lin_refuel@qq.com
*/
public class demo01 {
public static void main(String[] args) throws ClassNotFoundException {
//方式一:类名.class
Class<Student> c01 = Student.class;
System.out.println(c01);//最方便的方式
//方式二:
Class<? extends Student> c02 = new Student().getClass();//无奈的方式
System.out.println(c02);
//方式三
Class<?> c03 = Class.forName("com.itxs.demo01.Student");//最灵活的方式
System.out.println(c03);
}
}
运行结果:Student类的路径
反射构造方法的获取
Class获取构造方法四个方法概述
四个方法 | 作用 |
---|---|
getConstructor() |
获取公有的无参的构造方法,也可进行传递参数获取指定公有构造方法 |
getConstructors() |
获取到类中所有公有构造方法,形成一个数组 |
getDeclaredConstructor() |
可以根据参数获取一个指定的构造方法,公有和私有,等类型不限制,没有参数,默认为是无参构造方法 |
getDeclaredConstructors() |
获取类中所有的构造方法,形成一个数组, |
测试上面的四个方法
demo:
Student类,包含一些公有,私有,受保护的成员属性,构造方法,成员方法等
java
package com.itxs.demo01;
/**
* @Classname : Student
* @Description : TODO 学生类
* @Author : lin_refuel@qq.com
*/
public class Student {
//定义出学生的属性
//两个公有属性
public String name; //姓名
public int age; // 年龄
//两个私有属性
private float score;//成绩
private int sex;//性别
//两个受保护的属性
protected String interest;
protected int ranking;
// 一个默认的
int classid;
// 默认的无参构造方法
public Student() {
}
// 两个公有的构造方法
public Student(String name) {
this.name = name;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 两个私有的构造方法
private Student(String name, int age, float score) {
this.name = name;
this.age = age;
this.score = score;
}
private Student(String name, int age, float score, int sex) {
this.name = name;
this.age = age;
this.score = score;
this.sex = sex;
}
//两个受保护的构造方法
protected Student(String name, int age, float score, int sex, String interest) {
this.name = name;
this.age = age;
this.score = score;
this.sex = sex;
this.interest = interest;
}
protected Student(String name, int age, float score, int sex, String interest, int ranking, int classid) {
this.name = name;
this.age = age;
this.score = score;
this.sex = sex;
this.interest = interest;
this.ranking = ranking;
this.classid = classid;
}
//成员变量的get和set
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 float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public String getInterest() {
return interest;
}
public void setInterest(String interest) {
this.interest = interest;
}
public int getRanking() {
return ranking;
}
public void setRanking(int ranking) {
this.ranking = ranking;
}
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
", sex=" + sex +
", interest='" + interest + '\'' +
", ranking=" + ranking +
", classid=" + classid +
'}';
}
//*****************************************
//两个公有方法
public void monPu(){
System.out.println("我是无参公有方法");
}
public void monPu(String args){
System.out.println("我是带参公有方法,参数"+args);
}
private void monPri(){
System.out.println("我是无参私有方法");
}
private void monPri(String args){
System.out.println("我是带参私有方法,参数"+args);
}
protected void monPro(){
System.out.println("我是受保护的无参方法");
}
protected void monPro(String args){
System.out.println("我是受保护带参方法,参数"+args);
}
}
getConstructor()
java
package com.itxs.demo01;
import java.lang.reflect.Constructor;
/**
* @Classname : demo02
* @Description : TODO 反射 - 构造方法的获取
* @Author : lin_refuel@qq.com
*/
public class demo02 {
public static void main(String[] args) throws NoSuchMethodException {
// 获取一个Class对象,类名.class
Class<Student> stu01 = Student.class;
// 获取类公有无参的构造方法
Constructor<Student> c01 = stu01.getConstructor();
System.out.println(c01);//public com.itxs.demo01.Student()
}
}
运行结果:
getConstructors()
java
package com.itxs.demo01;
import java.lang.reflect.Constructor;
/**
* @Classname : demo02
* @Description : TODO 反射 - 构造方法的获取
* @Author : lin_refuel@qq.com
*/
public class demo02 {
public static void main(String[] args) throws NoSuchMethodException {
// 获取一个Class对象,类名.class
Class<Student> stu01 = Student.class;
// 获取类中所有的公有构造方法,形成一个数组
Constructor<?>[] c01 = stu01.getConstructors();
//对数组进行遍历
for (Constructor<?> c1 : c01) {
System.out.println(c1);
}
}
}
运行结果:
getDeclaredConstructor()
java
package com.itxs.demo01;
import java.lang.reflect.Constructor;
/**
* @Classname : demo02
* @Description : TODO 反射 - 构造方法的获取
* @Author : lin_refuel@qq.com
*/
public class demo02 {
public static void main(String[] args) throws NoSuchMethodException {
// 获取一个Class对象,类名.class
Class<Student> stu01 = Student.class;
// 获取类中指定的构造方法,或者不传参数获取默认方法
Constructor<Student> s01 = stu01.getDeclaredConstructor();
System.out.println("默认无参构造方法" + s01);
System.out.println("==========================");
// 获取 四个参数的私有构造方法
Constructor<Student> s02 = stu01.getDeclaredConstructor(String.class, int.class, float.class, int.class);
System.out.println("私有且带有四个参数的构造方法"+ s02);
}
}
运行结果:
getDeclaredConstructors()
java
package com.itxs.demo01;
import java.lang.reflect.Constructor;
/**
* @Classname : demo02
* @Description : TODO 反射 - 构造方法的获取
* @Author : lin_refuel@qq.com
*/
public class demo02 {
public static void main(String[] args) throws NoSuchMethodException {
// 获取一个Class对象,类名.class
Class<Student> stu01 = Student.class;
// 获取类中全部的构造方法形成数组
Constructor<?>[] s02 = stu01.getDeclaredConstructors();
//进行遍历
for (Constructor<?> s2 : s02) {
System.out.println(s2);
}
}
}
运行结果:
获取的构造方法进行实例化输出
java
package com.itxs.demo01;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @Classname : demo03
* @Description : TODO
* @Author : lin_refuel@qq.com
*/
public class demo03 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 反射获取一个类
Class<Student> stu01 = Student.class;
// 调用方法getConstructor,获取到带一个参数类型的构造方法
Constructor<Student> c01 = stu01.getConstructor(String.class);
// 获取的构造方法进行实例化,调用newInstance
Student new01 = c01.newInstance("小肆");
// 输出构造方法
System.out.println(new01);
}
}
运行结果:
获取私有的构造方法进行实例化,输出
java
package com.itxs.demo01;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @Classname : demo04
* @Description : TODO 获取类中私有构造方法进行实例化,输出
* @Author : lin_refuel@qq.com
*/
public class demo04 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 反射获取一个类
Class<Student> Stu01 = Student.class;
// 调用方法获取一个私有的构造方法
Constructor<Student> get01 = Stu01.getDeclaredConstructor(String.class, int.class, float.class, int.class);
// 关闭异常检测 true是关闭检测,false是开启异常检测
get01.setAccessible(true);
// 获取的私有构造方法进行实例化
Student s = get01.newInstance("小肆", 18, 88, 1);
System.out.println(s);
}
}
运行结果:
反射--获取Class中的成员变量
定义一个学生类
java
package com.itxs.demo01;
/**
* @Classname : Student
* @Description : TODO 学生类
* @Author : lin_refuel@qq.com
*/
public class Student {
//定义出学生的属性
//两个公有属性
public String name; //姓名
public int age; // 年龄
//两个私有属性
private float score;//成绩
private int sex;//性别
//两个受保护的属性
protected String interest;
protected int ranking;
// 一个默认的
int classid;
// 默认的无参构造方法
Student() {
}
// 两个公有的构造方法
public Student(String name) {
this.name = name;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 两个私有的构造方法
private Student(String name, int age, float score) {
this.name = name;
this.age = age;
this.score = score;
}
private Student(String name, int age, float score, int sex) {
this.name = name;
this.age = age;
this.score = score;
this.sex = sex;
}
//两个受保护的构造方法
protected Student(String name, int age, float score, int sex, String interest) {
this.name = name;
this.age = age;
this.score = score;
this.sex = sex;
this.interest = interest;
}
protected Student(String name, int age, float score, int sex, String interest, int ranking, int classid) {
this.name = name;
this.age = age;
this.score = score;
this.sex = sex;
this.interest = interest;
this.ranking = ranking;
this.classid = classid;
}
//成员变量的get和set
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 float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
if(sex>1){
System.out.println("性别非法,0:性别女,1性别男,默认性别男");
sex = 1;
System.exit(-1);//程序退出
}
this.sex = sex;
}
public String getInterest() {
return interest;
}
public void setInterest(String interest) {
this.interest = interest;
}
public int getRanking() {
return ranking;
}
public void setRanking(int ranking) {
this.ranking = ranking;
}
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
", sex=" + sex +
", interest='" + interest + '\'' +
", ranking=" + ranking +
", classid=" + classid +
'}';
}
//*****************************************
//两个公有方法
public void monPu(){
System.out.println("我是无参公有方法");
}
public void monPu(String args){
System.out.println("我是带参公有方法,参数"+args);
}
private void monPri(){
System.out.println("我是无参私有方法");
}
private void monPri(String args){
System.out.println("我是带参私有方法,参数"+args);
}
protected void monPro(){
System.out.println("我是受保护的无参方法");
}
protected void monPro(String args){
System.out.println("我是受保护带参方法,参数"+args);
}
}
getFields()
java
package com.itxs.demo01;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* @Classname : demo05
* @Description : TODO 反射获取类中的成员属性,进行赋值访问
* @Author : lin_refuel@qq.com
*/
public class demo05 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 反射获取一个对象
Class<Student> stu01 = Student.class;
// 调用方法获取stu01中的所有公有的变量
Field[] get01 = stu01.getFields(); // 公有变量的集合
for (Field get001 : get01) {
System.out.println(get001);
}
}
}
运行结果:
getField()
java
package com.itxs.demo01;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* @Classname : demo05
* @Description : TODO 反射获取类中的成员属性,进行赋值访问
* @Author : lin_refuel@qq.com
*/
public class demo05 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 反射获取一个对象
Class<Student> stu01 = Student.class;
// 调用方法getField(),可以获取指定成员变量
Field age = stu01.getField("age");//参数就是变量名字
System.out.println(age);
}
}
运行结果:
getDeclaredFields()
java
package com.itxs.demo01;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* @Classname : demo05
* @Description : TODO 反射获取类中的成员属性,进行赋值访问
* @Author : lin_refuel@qq.com
*/
public class demo05 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 反射获取一个对象
Class<Student> stu01 = Student.class;
// 获取stu01中所有的成员变量,
Field[] s01 = stu01.getDeclaredFields();//成员变量数组
// 进行遍历
for (Field s : s01) {
System.out.println(s);
}
}
}
运行结果:
getDeclaredField()
注意Student(学生类)中setAge方法
java
package com.itxs.demo01;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* @Classname : demo05
* @Description : TODO 反射获取类中的成员属性,进行赋值访问
* @Author : lin_refuel@qq.com
*/
public class demo05 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 反射获取一个对象
Class<Student> stu01 = Student.class;
// 获取类中私有成员变量sex的方式 TODO getDeclareField("变量名字")
Field sex = stu01.getDeclaredField("sex");
System.out.println(sex);
// 设置和访问里面变量名字的两种方式
//方式一: 常规的访问方式
// 获取里面的构造方法,获取 TODO 默认无参构造方法
Student student = stu01.getDeclaredConstructor().newInstance();
// sex设置
student.setSex(1);
System.out.println(student.getSex());//输出sex的值
// ******************************************************
//方式二:反射的方式
sex.setAccessible(true);// sex是私有变量,先进行异常检测关闭
sex.set(student,3);// 设置student对像里面的私有变量sex,TODO 可以绕开 student里面setAge里面的限制
System.out.println(sex.get(student));//获取student里面的sex的值
}
}
运行结果:
反射--获取类中的成员方法
java
package com.itxs.demo01;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @Classname : demo06
* @Description : TODO 反射 - 获取类中成员方法进行调用
* @Author : lin_refuel@qq.com
*/
public class demo06 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 反射获取一个类
Class<Student> stu01 = Student.class;
// TODO 获取类里面所有公有的方法,包括继承父类中的公有方法
// Method[] methods = stu01.getMethods();// Student类和父类中的公有成员方法数组
// for (Method method : methods) {
// System.out.println(method);
// }
//**********************************************************************
// TODO 反射的方式获取类里面的所有方法,不包含父类中的公有方法
// Method[] declaredMethods = stu01.getDeclaredMethods();
// for (Method declaredMethod : declaredMethods) {
// System.out.println(declaredMethod);
// }
//***********************************************************************
// TODO 反射方式 获取类里面指定的成员方法
// 获取类中公有成员方法 getMethod
Method monPu = stu01.getMethod("monPu");//获取Student里面的monPu方法
System.out.println(monPu);
//第一种常规调用方式,调用公有方法monPu
Constructor<Student> stu001 = stu01.getDeclaredConstructor(String.class, int.class, float.class);//获取一个私有构造方法
stu001.setAccessible(true);//私有构造方法进行调用关闭异常检测
Student s02 = stu001.newInstance("小肆", 18, 99);//构造方法实例化成对象
s02.monPu("在下小肆");
// 第二种调用方式调用里面的私有成员方法monPri
// 获取私有成员方法使用 - getDeclaredMethod
Method monPri = stu01.getDeclaredMethod("monPri", String.class);//获取到带一个参数的私有成员方法
monPri.setAccessible(true);
monPri.invoke(s02,"我是小肆二号");//调用实例化对象s02里面的monPri
}
}
通过配置文件实现不同的程序功能
一个后缀名为txt的文件,通过修改Classname和fangfaming实现调用不同的类里面的方法
在demo02包里面定义一个学生类
java
package com.itxs.demo02;
/**
* @Classname : Student
* @Description : TODO 学生类
* @Author : lin_refuel@qq.com
*/
public class Student {
public void learn(){
System.out.println("学生的职责就是好好学习,大概是可以早恋");
}
}
在demo02里面定义一个教师类
java
package com.itxs.demo02;
/**
* @Classname : Teacher
* @Description : TODO 教师类
* @Author : lin_refuel@qq.com
*/
public class Teacher {
public void tuition(){
System.out.println("老师的职责是好好教学,应该会注意学生早恋");
}
}
demo03里面定义一个测试类
java
package com.itxs.demo03;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* @Classname : demo01
* @Description : TODO
* @Author : lin_refuel@qq.com
*/
public class demo01 {
public static void main(String[] args) throws IOException, NoSuchMethodException, ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 通过配置文件的方式调用两个类中的方法
FileReader fr = new FileReader("D:/JAVA/ce/My.txt");//读取的目标文件
// 定义一个Properties,
Properties prop = new Properties();
// 读取目标文件fr里面的内容
prop.load(fr);
//测试读取
//System.out.println(prop);
//获取根据键获取对应的值
String p1 = prop.getProperty("Classname");//类名字
String p2 = prop.getProperty("fangfaming");//方法名字
//通过反射获取对象
Class<?> aClass = Class.forName("com.itxs.demo02." + p1);//获取到对象
//获取对象的构造方法
Constructor<?> c1 = aClass.getConstructor();
//构造方法进行实例化
Object o = c1.newInstance();
//反射获取类中方法
Method method = aClass.getMethod(p2);//
//进行调用
method.invoke(o);
//关闭流
fr.close();
}
}
运行结果:
教师类测试
学生类测试