J2EE基础:反射Reflect

本节知识总结


目录

本节知识总结

前言

一、反射是什么?

反射Java语言的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法

二、类类(类对象的三种获取方式)

1.Class.forName(完整类名)

2.类名.class

3.对象.getClass()

 三、反射实例化

用反射调用无参构造器用:newlnstance

 用反射调用有参构造器用:getConstructor 

用反射调用私(公)有的构造器用:getDeclaredConstructor

 *  ✍getConstructor与getDeclaredConstructor的区别:

四、反射动态方法调用

五、反射读写属性

总结


前言

在jdk的配置环境中   从俩个地方体现出:一个是XML解析 另一个是实体类 而实体类则需要运用反射
jdk里面jre转译:是将.java文件转化为.class的文件                    
而今天我们说的是反射  它是将.class文件转为.java文件           


一、反射是什么?

反射Java语言的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法

 接下来要学习的是框架,现在所学的都是把框架拆开学

首先框架设计模式(23种)+反射 


二、类类(类对象的三种获取方式)

1.Class.forName(完整类名)

2.类名.class

3.对象.getClass()

首先我们会用到一个Student实体类,里面有无参有参有返回无返回私有公开的构造方法,进行下面所有反射的使用

package com.xiehuiyi.class1;

public class Student {
    private String sid;

    private String sname;

    public Integer age;
    
    static{
        System.out.println("加载进jvm中!");
    }

    public Student() {
        super();
        System.out.println("调用无参构造方法创建了一个学生对象");
    }

    public Student(String sid) {
        super();
        this.sid = sid;
        System.out.println("调用带一个参数的构造方法创建了一个学生对象");
    }

    public Student(String sid, String sname) {
        super();
        this.sid = sid;
        this.sname = sname;
        System.out.println("调用带二个参数的构造方法创建了一个学生对象");
    }

    @SuppressWarnings("unused")
    private Student(Integer age) {
        System.out.println("调用Student类私有的构造方法创建一个学生对象");
        this.age = age;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public void hello() {
        System.out.println("你好!我是" + this.sname);
    }

    public void hello(String name) {
        System.out.println(name + "你好!我是" + this.sname);
    }

    @SuppressWarnings("unused")
    private Integer add(Integer a, Integer b) {
        return new Integer(a.intValue() + b.intValue());
    }
}

 建立一个Demo1类:

package com.xiehuiyi.class1;
/**
 * 获取类类的类对象的三种方式(识记)
 */
public class Demo1 {
public static void main(String[] args) throws Exception {
//    1.class.forName(完整类名)
    Class<Student> stuClz1 = (Class<Student>) Class.forName("com.xiehuiyi.class1.Student");
//2.类.class
    Class stuClz2=Student.class;
//3.类类的类对象的类实例.getClass();
    Class stuClz3=new Student().getClass();
}
}
 


 三、反射实例化

用反射调用无参构造器用:newlnstance

代码如下:

package com.xiehuiyi.class1;

public class Demo2 {
public static void main(String[] args) throws Exception {
    //拿到Studen文件
    Class<Student> stuClz1 = (Class<Student>) Class.forName("com.xiehuiyi.class1.Student");
    //调用无参方法
    //实例化
    Student stu1=(Student) stuClz1.newInstance();
    stu1.hello();//调用student类中的方法
}
}

输出结果如下就实例化成功: 

 如果没有无参构造方法(会报以下错误):

 原因:因为在很多框架底层都是通过无参构造器对这个类进行实例化的

 用反射调用有参构造器用:getConstructor 

 代码如下:

package com.xiehuiyi.class1;

import java.lang.reflect.Constructor;

public class Demo2 {
public static void main(String[] args) throws Exception {
    //拿到Studen文件
    Class<Student> stuClz1 = (Class<Student>)

    //调用有参构造器
    Constructor<Student> c = stuClz1.
getConstructor(String.class);//括号里填的是有参的参数的类型,如果有多个可以一样往后面加
    Student s1 = c.newInstance("s001");
}
}

 输出结果如下就实例化成功:

 如果调用私有的:

所以用下面的方法👍  

用反射调用私(公)有的构造器用:getDeclaredConstructor

 代码如下:

package com.xiehuiyi.class1;

import java.lang.reflect.Constructor;

public class Demo2 {
public static void main(String[] args) throws Exception {
    //拿到Studen文件
    Class<Student> stuClz1 = (Class<Student>)

    //调用私有有参构造器
   Constructor<Student> c2 = stuClz1.
getDeclaredConstructor(Integer.class);//括号里填的是有参的参数的类型,如果有多个可以一样往后面加
    c2.setAccessible(true);//给私有化授权
    Student s2=c2.newInstance(26);
}
}

 输出结果如下就实例化成功:

如果没有授权setAccessible(true)(报错):

 *  ✍getConstructor与getDeclaredConstructor的区别:

   getDeclaredConstructor可以获取到私有的有参无参构造器以及共有的
    而getConstructor只能获取公有有参构造器
 


四、反射动态方法调用

1.getMethod(方法名 参数数据类型(无参数传null))获取公共方法

2.getDeclaredMethod(方法名 参数数据类型(无参数传null))获取私有公有方法

代码如下:

package com.xiehuiyi.class1;

import java.lang.reflect.Method;

/**
 * 反射动态方法调用
 */
public class Demo3 {
public static void main(String[] args) throws Exception {
    //拿到Studen文件
    System.out.println("====调用无参======");    
    Class<Student> stuClz1 = (Class<Student>) Class.forName("com.xiehuiyi.class1.Student");
        Student s=(Student) stuClz1.newInstance();
        
        Method m1 = stuClz1.getDeclaredMethod("hello");
        Method m = stuClz1.getMethod("hello");
        //m1.invoke(obj, args);
        //参数1:类实例,在这里指的是Student类实例
        //参数2:当前被调用的方法,传递的参数值        
        //invoke的返回值,就是被放射调用的方法的返回值,如果被调用的方法是void,那么返回null

        System.out.println(m1.invoke(s));
        System.out.println(m.invoke(s));
    
        System.out.println("=======调用有参=======");
        Method m2 = stuClz1.getDeclaredMethod("hello",String.class);
        System.out.println(m2.invoke(s,"xhy"));
        System.out.println("======有参私有=======");
        Method m3 = stuClz1.getDeclaredMethod("add",Integer.class,Integer.class);
        m3.setAccessible(true);
        System.out.println(m3.invoke(s,50, 2));


}
}
 

输出结果:

如果用 .getMethod调用私有,报错:

*ps 得出getMethod只能调用公开的


五、反射读写属性

getDeclaredField

getDeclaredFields

package com.xiehuiyi.class1;

import java.io.File;
import java.lang.reflect.Field;

/**
 * 反射读写属性
 * @author zjjt
 *
 */
public class Demo4 {
public static void main(String[] args) throws Exception {
    //获得类对象
    Class<Student> stuClz1 = (Class<Student>) Class.forName("com.xiehuiyi.class1.Student");
    //实例化一个学生
    Student s=(Student) stuClz1.newInstance();
    Field f = stuClz1.getDeclaredField("sname");
    f.setAccessible(true);
    //反射写属性
    f.set(s, "xhy");
    System.out.println(s.getSname());
    //反射读属性
    System.out.println(f.get(s));
    
    //比较oop读取属性值的方式
    Student st=new Student("s002","ls");
    st.age=18;
    System.out.println(st.getSid());
    System.out.println(st.getSname());
    System.out.println(st.age);
    //与反射读取属性
    Field[] fields = stuClz1.getDeclaredFields();
    for (Field ff : fields) {
        ff.setAccessible(true);
        System.out.println(ff.get(st));
    }
    
    
}
}
ps:反射对比oop读取属性值的方式更方便

输出结果: 


总结

在本节中类对象的三种获取方式需要我们识记,其他我们需要更深入的了解认识它用它,课后可以再去了解一下获取访问修饰符:getModifiers()

今天的内容就到这了!我们下期再见!希望以上内容能对你有帮助,当然有什么错误之处还望大佬指正!谢谢😘

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值