java反射

一.反射的定义

1.java反射机制的核心是在程序运行时动态加载类,并获取类的详细信息,进一步操作类的属性,方法等.在jvm得到class对象之后再通过class对象进行反编译,获取对象的各种信息.

2.java反射的应用让我们对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意方法和属性.这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

二.通过反射获取class对象的三种方式

注意:class类是反射的源头,每个类都有唯一一个class对象,不能通过new来获取,类加载过程中class字节码文件加载到内存中,java虚拟机通过调用类加载器中的defineClass方法自动在堆中构造这个类对应的class对象.

方式一:new 对象.getClass();

方式二:Class.forName("类的路径");

方式三:类名.class;

举例如下:

//新建一个student类和teacher类
public class student {
    private String name;
    private int age;


    public student() {
    }

    public student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "student{name = " + name + ", age = " + age + "}";
    }
}
public class teacher {
    private String name;
    public int age;

    public teacher() {
    }

    public teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "teacher{name = " + name + ", age = " + age + "}";
    }
        public void testMethod1(){
        System.out.println("测试方法一");
    }
    private void testMethod2(){
        System.out.println("测试方法二:私有");
    }
}
//获取class
public class fs {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //第一种:new对象获取class
        student s1 = new student();
        s1.getClass();
        //第二种:通过路径获取
        System.out.println(Class.forName("fs.student"));
        //第三种:通过类名获取
        Class<student> studentClass = student.class;
        student student2 = studentClass.newInstance();
        student2.setName("张三");
        student2.setAge(11);
        System.out.println(student2);
        System.out.println(studentClass);
        //通过类名获取
        Class<teacher> teacherClass = teacher.class;
        System.out.println(teacherClass.newInstance());


    }
}

三.通过反射获取类的对象

方式一:通过class对象的newInstance()方法

方式二:通过Construct对象的newInstance();

public class test1 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
        //方式一
        Class<teacher> teacherClass = teacher.class;
        teacher teacher = teacherClass.newInstance();
        teacher.setName("李老师");
        teacher.setAge(30);
        System.out.println(teacher);
//方式二
        Class<?> aClass = Class.forName("fs.teacher");
        Constructor<?> constructor = aClass.getConstructor(String.class,int.class);
        System.out.println(constructor.newInstance("王老师",30));
        


    }
}
//运行结果如下:
teacher{name = 李老师, age = 30}
teacher{name = 王老师, age = 30}

四.反射获取类的字段

1.getFields();获得某类的所有公共字段,包括父类的字段(返回值为数组)

2.getDeclaredFileds();获得某个类所有声明的字段,public、private和proteced,但是不包括父类的声明字段(返回值为数组)

3.getField(String name);根据字段名获取公共字段

4.getDeclaredField(String name);根据字段名可以获取所有类型的字段

5.常用方法:setAccessible(true);来访问私有属性

6.获取注解:getAnnotation(注解.class):获取属性上的注解对象

举例:

public class field {
    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
        Field[] declaredFields = teacher.class.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            //获取所有字段
            System.out.println("全部:"+declaredField);
            //获取字段名
            System.out.println("字段名:"+declaredField.getName());
            //获取字段修饰符
            System.out.println("修饰符:"+declaredField.getModifiers());
            //结果
//            全部:private java.lang.String fs.teacher.name
//            字段名:name
//            修饰符:2
//            全部:public int fs.teacher.age
//            字段名:age
//            修饰符:1

        }
        Field[] fields = teacher.class.getFields();
        for (Field field : fields) {
            System.out.println("全部2:"+field);
            System.out.println("修饰符2:"+field.getModifiers());
            //结果
            // 全部2:public int fs.teacher.age
            //修饰符2:1

        }
        //根据字段名获取公共字段
        System.out.println(teacher.class.getField( "age"));
        //输出结果:public int fs.teacher.age
        System.out.println(teacher.class.getDeclaredField("name"));
        //输出结果:private java.lang.String fs.teacher.name
        //常用方法:setAccessible(true);来访问私有属性
        teacher teacher = teacher.class.newInstance();
        Field name = teacher.class.getDeclaredField("name");
        name.setAccessible(true);
        name.set(teacher,"李华");
        System.out.println(teacher);

    }

五.反射获取类中的方法

1.getMethods():获取包括自身和继承过来所有public方法

2.getDeclaredMethods():获取自身类中所有的方法(*不包括继承的,和访问权限无关*)

3.getMethod(String methodName,Class<?>... parameterTypes):表示调用指定的一个公共的方法(包括继承的)参数: methodName: 表示被调用方法的名字,parameterTypes:表示被调用方法的参数的Class类型如String.class

4.getDeclaredMethod(String name,Class<?>... parameterTypes):表示调用指定的一个本类中的方法(不包括继承的)参数:methodName: 表示被调用方法的名字,parameterTypes:表示被调用方法的参数的Class类型如String.class

5.invoke(通过反射建的类):执行方法体

//teacher类新建两个方法用来测试
    public void testMethod1(){
        System.out.println("测试方法一");
    }
    private void testMethod2(){
        System.out.println("测试方法二:私有");
    }
//具体应用
public class method {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<teacher> teacherClass = teacher.class;
        teacher teacher = teacherClass.newInstance();
        System.out.println(teacherClass.getMethods());
        //获取本身以及父类所有public方法
        Method[] methods = teacherClass.getMethods();
        for (Method method : methods) {
//            System.out.println(method);

        }
        //获取本类所有类型方法,不限制修饰符
        Method[] declaredMethods = teacherClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
//            System.out.println(declaredMethod);
        }

        System.out.println(teacherClass.getMethod("testMethod1"));//只能获取公共
        System.out.println(teacherClass.getDeclaredMethod("testMethod2", null));//能获取全部
        //输出结果
//        public void fs.teacher.testMethod1()
//        private void fs.teacher.testMethod2()
        Method testMethod1 = teacherClass.getMethod("testMethod1");
        //执行该方法
        testMethod1.invoke(teacher);
        //输出结果:
//        测试方法一

六.反射获取构造方法

1.getConstructors():获取本类所有的公有构造方法

2.getDeclaredConstructos():获取本类所有的构造方法

3.getConstructor(Class…<?> parameterTypes):获取本类中参数类型匹配的公有构造方法

4.getDeclaredConstructor(Class…<?> parameterTypes):获取本类中参数类型匹配的构造方法

public class construct {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException {
        Class<b> bClass = b.class;
        b b = bClass.newInstance();
        Constructor<?>[] constructors = bClass.getConstructors();
        //获取本类的所有构造方法
        Constructor<?>[] declaredConstructors = bClass.getDeclaredConstructors();
        System.out.println(declaredConstructors);
        //获取本类中参数类型匹配的公有构造方法
       bClass.getConstructor(String.class);
       //获取本类中参数类型匹配的构造方法
        bClass.getDeclaredConstructor(Integer.class);


    }

}
class a{
    public a(){
        System.out.println("父类的空参构造");
    }
    public a(String name){
        System.out.println("父类的带参构造");
    }

}
class b extends a{
    public b(){
        System.out.println("子类的无参构造");
    }
    public b(String name){
        System.out.println("子类的带参构造");
    }
    private b(Integer age){
        System.out.println("私有的带参构造");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值