Java反射

一:了解

反射就是:加载类,并允许以编程的方式解刨类中的各种成分(成员变量、方法、构造器等)。

二:反射就是学习获取类的信息,操作它们

1.反射第一步:加载类,获取类的字节码:Class对象

2.获取类的构造器:Constructor对象

3.获取类的成员变量:Filed对象

4.获取类的成员方法:Methon对象

三:获取Class对象的三种方式

1.Class c = 类名.class;

2.调用Class提供的方法:public static Class forName(String package);

3.Object提供的方法:public Class getClass(); Class c = 对象.getClass();

4.示例:

public class Test1 {
    public static void main(String[] args) throws Exception {
        Class c1 = Student.class;

        Class c2 = Class.forName("High.Student");

        Student s = new Student();
        Class c3 = s.getClass();

        System.out.println(c1.getName());//全类名
        System.out.println(c1.getSimpleName());//简类名
    }
}

四:获取类的构造器、并对其进行操作

1.Class提供了从类中获取构造器的方法

getConstructors() 获取全部构造器(只能获取public修饰的)

getDeclaredConstructors() 获取全部构造器(只要存在就能拿到)

getConstructor(Class<?>... parameterTypes) 获取某个构造器(只能获取public修饰的)

getDeclaredConstructor(Class<?>... parameterTypes) 获取某个构造器(只要存在就能拿到)

2.获取类构造器的作用:依然是初始化对象返回

Constructor提供的方法

newInstance(Object... initargs) 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回

setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)

3.示例:

import java.lang.reflect.Constructor;

public class Test2 {
    public static void main(String[] args) throws Exception {
        getConstructors();
        getConstructor();
    }
    public static void getConstructors(){
        //1.反射第一步必须先得到这个类的对象
        Class s = Student.class;
        //        Constructor[] constructors = s.getConstructors();
        Constructor[] constructors = s.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName()+"------->"+
                               constructor.getParameterCount());//获取参数的个数
        }
    }
    public static void getConstructor() throws Exception {
        Class s = Student.class;
        //        Constructor c1 = s.getConstructor();
        Constructor c1 = s.getDeclaredConstructor();
        c1.setAccessible(true);//禁止检查访问权限
        Student ss1 = (Student) c1.newInstance();
        System.out.println(c1.getName()+"-------->"+
                           c1.getParameterCount());
        System.out.println(ss1);


        //        Constructor c2 = s.getConstructor(String.class, int.class);
        Constructor c2 = s.getDeclaredConstructor(String.class, int.class);
        c2.setAccessible(true);//禁止检查访问权限
        Student ss2 = (Student) c2.newInstance("蔡建宇", 18);
        System.out.println(c1.getName()+"-------->"+
                           c2.getParameterCount());
        System.out.println(ss2);
    }
}

五:获取类的成员变量

1.Class提供了从类中获取成员变量的方法

getFields() 获取类的全部成员变量(只能获取public修饰的)

getDeclareFields() 获取类的全部成员变量(只要存在就能拿到)

getField(String name) 获取类的某个成员变量(只能获取public修饰的)

getDeclareField(String name) 获取类的某个成员变量(只要存在就能拿到)

2.获取到成员变量的作用:依然是赋值,取值

set(Object obj, Object value) 赋值

get(Object obj) 取值

setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)

3.示例:

import java.lang.reflect.Field;

public class Test3 {
    public static void main(String[] args) throws Exception {
        getFields();
        getField();
    }
    public static void getFields(){
        Class s = Student.class;
        Field[] fields = s.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName()+"----->"+
                               field.getType());
        }
    }
    public static void getField() throws Exception {
        Class s = Student.class;
        Student ss = new Student();

        Field Fname = s.getDeclaredField("name");
        System.out.println(Fname.getName()+"----->"+
                           Fname.getType());
        Fname.setAccessible(true);
        Fname.set(ss,"王凯");
        System.out.println(Fname.get(ss));

        Field Fage = s.getDeclaredField("age");
        System.out.println(Fage.getName()+"----->"+
                           Fage.getType());
        Fage.setAccessible(true);
        Fage.set(ss,18);
        System.out.println(Fage.get(ss));
    }
}

六:获取类的成员方法

1.Class提供了从类中获取成员方法的API

getMethods() 获取类的全部成员方法(只能获取public修饰的)

getDeclaredMethods() 获取类的全部成员方法(只要存在就能拿到)

getMethod(String name , Class<?>... parameterTypes) 获取类的某个成员方法(只能获取public修饰的)

getDeclaredMethod(String name , Class<?>... parameterTypes) 获取类的某个成员方法(只要存在就能拿到)

2.成员方法的作用:依然是执行

invoke(Object obj, Object... args) 触发某个对象的该方法执行

setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)

3.示例:

import java.lang.reflect.Method;

public class Test4 {
    public static void main(String[] args) throws Exception {
        getMethods();
        getMethod();
    }
    public static void getMethods(){
        Class c = Student.class;

        Method[] declaredMethods = c.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName()+"---->"+
                               declaredMethod.getParameterCount()+"----->"+
                               declaredMethod.getReturnType());
        }
    }
    public static void getMethod() throws Exception {
        Class c = Student.class;

        Method study = c.getDeclaredMethod("Study");//调用无形参的
        System.out.println(study.getName()+"---->"+
                           study.getParameterCount()+"---->"+
                           study.getReturnType());

        Method eat = c.getDeclaredMethod("eat", String.class);//调用有形参的
        System.out.println(eat.getName()+"---->"+
                           eat.getParameterCount()+"---->"+
                           eat.getReturnType());

        Student s = new Student();
        study.setAccessible(true);
        study.invoke(s);

        eat.setAccessible(true);
        eat.invoke(s,"饭");
    }
}

七:反射的作用

1.基本作用:可以得到一个类的全部成分,然后操作

2.可以破坏封装性

3.最重要的用途是:适合做Java框架,基本上,主流的框架都会基于反射设计出一些通用的功能

4.应用场景:对于任意一个对象,该框架都可以吧对象的字段名和对应的值,保存到文件中去。

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;

public class JavaFrame {
    public static void saveObject(Object obj) throws Exception {
        PrintStream ps = new PrintStream(new FileOutputStream("D:\\练习\\TheLast\\src\\High\\data.txt",true));

        Class c = obj.getClass();
        String simpleName = c.getSimpleName();
        ps.println("----------"+simpleName+"------------");

        Field[] declaredFields = c.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            ps.println(declaredField.getName()+"--------->"+declaredField.get(obj));
        }
        ps.close();
    }
}
public class Test5 {
    public static void main(String[] args) throws Exception {
        Student S = new Student("蔡建宇",18);
        Teacher T = new Teacher("李鹤声","语文",54);
        JavaFrame.saveObject(S);
        JavaFrame.saveObject(T);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值