Java 反射

反射是框架设计的灵魂

一、反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.反射是java语言的一种机制,利用反射机制动态的实例化对象(构造函数)、读写属性、调用方法。

简单来说反射是java语言的一种机制,利用反射机制动态的实例化对象(构造函数)、读写属性、调用方法。

反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

 二、反射的使用(这里使用Student类做演示)

1、获取Class对象的三种方式
1.1 Object ——> getClass();
1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
1.3 通过Class类的静态方法:forName(String  className)(常用)
其中1.1是因为Object类中的getClass方法、因为所有类都继承Object类。从而调用Object类来获取

 先写一个Student类。

package com.zking.reflection;

 import java.io.Serializable;
 
public class Student implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 6921501844505269294L;
 
    private String sid;
 
    private String sname;
 
    public Integer age;
 
    public Student() {
        System.out.println("调用无参构造方法创建了一个学生对象");
    }
 
    public Student(String sid) {
        this.sid = sid;
        System.out.println("调用带一个参数的构造方法创建了一个学生对象");
    }
 
    public Student(String sid, String sname) {
        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());
    }
 
    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";
    }
}


package com.zking.reflection;
 
public class Demo01 {
 
    public static void main(String[] args) throws Exception {
        //java反射是java中的一种重要机制
        //它可以动态的实例化对象,读写属性,调用方法
        
        //一切反射相关的代码都从获得类对象开始
        //获得类对象的方式
        //1.类名.class
        Class clazz = Student.class;
        System.out.println(clazz);
        
        System.out.println("-----------------");
        //2.对象名.getClass();
        Student stu = new Student();//这一new 产生一个Student对象,一个Class对象。
        Class clazz1 = stu.getClass();
        System.out.println(clazz1);
        
        System.out.println("-----------------");
        //3.Class.forName(全限定名/全路径名) 最常用
        Class clazz2 = Class.forName("com.zking.reflection.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
        System.out.println(clazz2);
        
        System.out.println(clazz==clazz1);//判断三种方式是否获取的是同一个Class对象    true
        System.out.println(clazz.getSimpleName());//获取类名
        System.out.println(clazz.getTypeName());//获取全限定名
        System.out.println(clazz.getPackage());//获取包名
    }
 
}

 

三种方式常用第三种,第一种需要导入类的包,依赖太强,不导包就抛编译错误。第二种对象都有了还要反射干什么。一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。

2、使用反射实例化对象

package com.zking.reflection;
 
import java.lang.reflect.Constructor;
 
public class Demo02 {
 
    public static void main(String[] args) throws Exception {
        //java反射是java中的一种重要机制
        //它可以动态的实例化对象,读写属性,调用方法
        
        //一切反射相关的代码都从获得类对象开始
        
        //Class.forName(全限定名/全路径名) 最常用
        Class clazz = Class.forName("com.zking.reflection.Student");
        //实例化对象
//        Student stu =(Student)clazz.newInstance();
//        System.out.println(stu);
        
        //通过构造方法实例化对象
        //1.获取无参公有构造方法对象
//        Constructor constructor = clazz.getConstructor();
//        //2.实例化对象
//        Object obj = constructor.newInstance();
//        System.out.println(obj);
        
        
//        Student stu = new Student("001");
//        System.out.println(stu);
        
        //获取有参公有构造方法对象
//        Constructor constructor = clazz.getConstructor(String.class,String.class);
//        //实例化对象
//        Object obj = constructor.newInstance("001","小黄");
//        System.out.println(obj);
    
        //获取有参私有构造方法对象
        Constructor constructor = clazz.getDeclaredConstructor(Integer.class);
        //如果是私有构造方法,必须打开方法的访问限制
        constructor.setAccessible(true);
        //实例化对象
        Object obj = constructor.newInstance(111);
        System.out.println(obj);
    }
}

3、使用反射读写属性


package com.zking.reflection;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
 
public class Demo03 {
 
    public static void main(String[] args) throws Exception {
        //java反射是java中的一种重要机制
        //它可以动态的实例化对象,读写属性,调用方法
        
        //一切反射相关的代码都从获得类对象开始
        
        //Class.forName(全限定名/全路径名) 最常用
        Class clazz = Class.forName("com.zking.reflection.Student");
        
        Student stu = (Student)clazz.newInstance();//实例化对象
        
 
        //读写属性
        //1.获取属性对象
        Field field = clazz.getDeclaredField("sid");
        //2.打开访问限制
        field.setAccessible(true);
        //3.写属性
        field.set(stu, "001");
        //4.读属性
        Object obj = field.get(stu);
        System.out.println(obj.toString());
        
        System.out.println(field.getName());//获取属性名
        System.out.println(field.getType());//获取属性类型
        System.out.println(field.getModifiers());//获取属性访问修饰符
        
    
//        Field field=cla.getField(“属性名”);
//        field.getName();            -->获取属性名            
//        filed.getType();            -->获取属性类型        
//        field.getModifiers();        -->获取属性访问修饰符    
//        field.set(Object,Object);     -->设置属性值,参数1:要设置属性所在对象;参数2:要设置的值;    
//        field.get(Object);            -->获取属性值,参数:要获取属性值的对象                
//        clazz.getDeclaredField(“属性名”);    -->获取单个属性(私有、公有、受保护、默认、静态)    
//        clazz.getDeclaredFields();        -->获取所有属性(私有、公有、受保护、默认、静态)
        
    }
}

 4、使用反射调用方法

package com.zking.reflection;
 
import java.lang.reflect.Method;
 
public class Demo04 {
 
    public static void main(String[] args) throws Exception {
        //java反射是java中的一种重要机制
        //它可以动态的实例化对象,读写属性,调用方法
        
        //一切反射相关的代码都从获得类对象开始
        
        //Class.forName(全限定名/全路径名) 最常用
        Class clazz = Class.forName("com.zking.reflection.Student");
        Student stu = (Student)clazz.newInstance();//实例化对象
        stu.setSname("牛马");
        //调用方法
        //1.获得方法对象
//        Method method = clazz.getDeclaredMethod("hello",String.class);
//        //2.打开方法访问限制
//        method.setAccessible(true);
//        //3.调用方法
//        method.invoke(stu,"大黄");
        
        //1.获得方法对象
//        Method method = clazz.getDeclaredMethod("add",Integer.class,Integer.class);
//        //2.打开方法访问限制
//        method.setAccessible(true);
//        //3.调用方法
//        Object invoke = method.invoke(stu,88,99);
//        System.out.println(invoke);
        
        //获取类对象中所有实现接口列表
        Class[] classes = clazz.getInterfaces();
        for (Class class1 : classes) {
            System.out.println(class1);
        }
        
        //获得父类对象
        clazz.getSuperclass();
        
        
        //无参无返回、无参有返回、有参无返回、有参有返回
//        根据类得到类的方法
//        cla.getMethod();            -->获取单个公有方法
//        cla.getDeclaredMethod();    -->获取当个方法(包括私有、受保护、默认、公有)
//        cla.getMethods();            -->获取所有公有方法
//        cla.getDeclaredMethods();    -->获取所有的方法(包括私有、受保护、默认、公有)
//        根据类得到类的构造方法
//        cla.getConstrutor();        -->获取单个公有构造方法
//        cla.getDeclaredConstrutor();-->获取单个构造方法(包括私有、受保护、默认、公有)
//        cla.getConstrutors();        -->获取所有的公有构造方法
//        cla.getDeclaredConstrutors();-->获取所有的构造方法(包括私有、受保护、默认、公有)
        
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值