文章目录
前言
java反射机制的理解与运用
提示:以下是本篇文章正文内容,下面案例可供参考
一、反射是什么?
简单的来说反射就是把Java类中的各个部分如方法、变量、构造器等映射称一个对象
1、Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于 Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
2、加载完类之后,在堆内存的方法区中就产生了一个clas类型的对象(一个类只有一个Cass对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。
二、通过声明 xxx 类所在包的完整名完成反射操作
1、反射访问构造方法
1.1要被访问构造方法的类声明如下
package lesson20210629;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Student {
/**
* 构造方法
*/
public Student() {//无参构造方法
System.out.println("这里是无参构造方法");
}
public Student(String name){//有参构造方法
System.out.println("名称为"+name);
}
public Student(String name,int age){//不同参数构造方法
System.out.println("名称为"+name+",年龄为:"+age);
}
private Student(int age){//私有属性构造方法
System.out.println("私有年龄为"+age);
}
}
1.2、访问无参构造方法
public static void method01(String addr){
//路径:lesson20210629/Student
try {
Class clazz = Class.forName(addr);//代表Student类在内存中的字节码对象
System.out.println(clazz);
Constructor cs = clazz.getConstructor();//获取到构造方法
Student s = (Student) cs.newInstance();//通过无参构造创建
}catch (Exception e){
e.printStackTrace();
}
}
1.3访问有参构造方法
public static void method02(String addr){
//路径:lesson20210629/Student
try {
Class clazz = Class.forName(addr);//代表Student类在内存中的字节码对象
System.out.println(clazz);
Constructor cs = clazz.getConstructor(String.class,int.class);//获取到构造方法
Student s = (Student) cs.newInstance("qn",18);//通过有参构造创建
}catch (Exception e){
e.printStackTrace();
}
}
1.3、访问私有的参构造方法
public static void method03(String addr){
//路径:lesson20210629/Student
try {
Class clazz = Class.forName(addr);//代表Student类在内存中的字节码对象
System.out.println(clazz);
Constructor cs = clazz.getDeclaredConstructor(int.class);//获取到私有化构造方法
cs.setAccessible(true);//暴力反射
Student s = (Student) cs.newInstance(20);//通过有参构造创建
}catch (Exception e){
e.printStackTrace();
}
}
1.4、main方法
public class Test01 {
public static void main(String[] args) {
method01("lesson20210629.Student");
method02("lesson20210629.Student");
method03("lesson20210629.Student");
}
}
1.5、运行结果
2.反射访问方法
2.1、要被访问自定义方法的类声明如下
package lesson20210629;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Student {
/**
* 自定义方法
*/
public void showMsg(){//无参无返回方法
System.out.println("无参无返回方法");
}
public void setName(String name){//有参无返回方法
System.out.println("有参,值为:"+name);
}
public String getName(){//无参有返回方法
System.out.println("带返回值的方法");
return "qn";
}
private void youName(){//私有无参无返回方法
System.out.println("私有你的名字");
}
//特殊参数
public void setBirthday(Date birthday){
System.out.println("你的生日:"+new SimpleDateFormat("yyyy-mm-dd").format(birthday));
}
//参数是数组
public void addStuName(String []names){
int i = 0;
for (String name:names) {
System.out.println(name+(i++==names.length-1?"":","));
}
}
}
2.2无参构造方法访问不同参数有无返回值方法
//无参构造方法访问无参无返回值方法
public static void method01(String addr){
try {
Class clazz = Class.forName(addr);
//通过无参构造方法创建对象
Student s = (Student) clazz.newInstance();
Method m = clazz.getMethod("showMsg",null);//参数为空可写可不写
m.invoke(s);//调用方法
}catch (Exception e){
e.printStackTrace();
}
}
//无参构造方法访问有参无返回值方法
public static void method02(String addr){
try {
Class clazz = Class.forName(addr);
//通过无参构造方法创建对象
Student s = (Student) clazz.newInstance();
Method m = clazz.getMethod("setName",String.class);//参数为空可写可不写
m.invoke(s,"qn");//调用方法
}catch (Exception e){
e.printStackTrace();
}
}
//无参构造方法访问无参有返回值方法
public static void method03(String addr) {
try {
Class clazz = Class.forName(addr);
//通过无参构造方法创建对象
Student s = (Student) clazz.newInstance();
Method m = clazz.getMethod("getName");//参数为空可写可不写
String name = (String) m.invoke(s);//调用方法
System.out.println("有返回值:" + name);
} catch (Exception e) {
e.printStackTrace();
}
}
//无参构造方法访问私有化无参无返回值方法
public static void method04(String addr) {
try {
Class clazz = Class.forName(addr);
//通过无参构造方法创建对象
Student s = (Student) clazz.newInstance();
Method m = clazz.getDeclaredMethod("youName");//参数为空可写可不写
m.setAccessible(true);//暴力
m.invoke(s);//方法的调用
} catch (Exception e) {
e.printStackTrace();
}
}
public static void method05(String addr){
try {
Class clazz = Class.forName(addr);
//通过无参构造方法创建对象
Student s = (Student) clazz.newInstance();
Method m = clazz.getMethod("setBirthday", Date.class);//参数为空可写可不写
m.invoke(s,new Date());//调用方法
}catch (Exception e){
e.printStackTrace();
}
}
public static void method06(String addr){
try {
Class clazz = Class.forName(addr);
//通过无参构造方法创建对象
Student s = (Student) clazz.newInstance();
Method m = clazz.getMethod("addStuName", String[].class);//参数为空可写可不写
// m.setAccessible(true);
m.invoke(s,(Object)new String[]{"123","1234","12345"});//调用方法
}catch (Exception e){
e.printStackTrace();
}
}
2.3、main方法
public class Test02 {
public static void main(String[] args) {
method01("lesson20210629.Student");
method02("lesson20210629.Student");
method03("lesson20210629.Student");
method04("lesson20210629.Student");
method05("lesson20210629.Student");
method06("lesson20210629.Student");
}
}
2.4运行结果
3、反射访问属性
3.1、要被访问自定义属性的类声明如下
package lesson20210629;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Student {
private String name;
public int age;
public static double height;
private Date birthday;
}
3.1、访问属性的方式
package lesson20210629;
import java.lang.reflect.Field;
//反射属性
public class Test03 {
public static void main(String[] args) throws Exception {
method01("lesson20210629.Student");
method02("lesson20210629.Student");
}
//公有化属性
public static void method01(String addr) throws Exception{
Class clazz = Class.forName(addr);
Student s = (Student) clazz.newInstance();
//获取属性
Field f = clazz.getField("age");
//set赋值
f.set(s,23);
// s.age = 23;//也可以
//get输出
int age = (int) f.get(s);
// age = s.age;//也可以
System.out.println(age);
}
//私有化属性
public static void method02(String addr) throws Exception{
Class clazz = Class.forName(addr);
Student s = (Student) clazz.newInstance();
//获取属性
Field f = clazz.getDeclaredField("name");
f.setAccessible(true);//暴力
//set赋值
f.set(s,"qn");
// s.age = 23;//也可以
//get输出
String name = (String)f.get(s);
// age = s.age;//也可以
System.out.println(name);
}
}
3.2、运行结果
总结
反射机制作用:一般用于做框架的,把抽象的底层代码反射到日常的开发中