java反射概述

jvaa反射概述

java反射机制:是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用再编译器就完成确定,在运行期仍然可以扩展

一、获取Class类的对象

我们想通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象

这里有三种方式获取Class类型的对象

(1)使用类的class属性来获取该类对应的Class对象。比如:Student.class将会返回Student类对应的Class对象

(2)调用对象的getClass()方法,返回该对象所属类对应的Class对象

该方法是Object类中的方法,所有的Java对象都可以调用该方法

(3)使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径

//反射要做的就是:通过这个构造方法对象里面的方法来创建对象

  • 反射机制极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力

  • 通过反射机制可以让程序创建和控制任何类的对象,无需提前编码目标类

  • 反射机制是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中

  • 反射可以在不修改代码的情况下通过修改配置文件来实现调用不同类和方法

  • 所以它能够动态编译和创建对象,极大的激发了变成语言的灵活性,强化了多态的特性,进一步提高了面向对象变成的抽象能力,因而受到编程界的青睐

package util;
​
public class Student {
        private String name;
        private int age;
        public String address;
        public Student(){}
        public Student(String name , int age,String address)
        {
            this.name = name;
            this.age = age;
            this.address = address;
        }
        private Student(String name){
                this.name = name;
        }
        public String getName(){return name;}
        public void setName(String name){this.name = name;}
        public String getAddress(){return address;}
        public void setAddress(String address){this.address = address;}
        public int getAge(){return age;}
        public void setAge(int age){this.age = age;};
        //成员方法,一个私有,四个公共
        private void function(){
                System.out.println("function");
        }
        public void method1(){
                System.out.println("method");
        }
        public void method2(String s){
                System.out.println("method"+s);
        }
        public String method3(String s,int i)
        {
                return s+","+i;
        }
        public String toString(){
                return "Student:name="+name+" , "+"age=:"+age+" , " +"address=:"+address;
        }
​
}
public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        //使用类的class属性来获取该类对应的Class对象
        Class<Student> c1 = Student.class;
        System.out.println(c1);
​
        Class<Student> c2 = Student.class;
        System.out.println(c1 == c2);
        System.out.println("----------");
​
        //调用对象的getClass()方法,返回该对象所属类对应的Class对象
        Student s = new Student();
        Class<? extends Student> c3 = s.getClass();
        System.out.println(c1 == c3);
        System.out.println("----------");
​
        //使用Class类中的静态方法forName(String className)
        Class<?> c4 = Class.forName("util.Student");//完全路径
        System.out.println(c1 == c4);
}
}

二、反射获取构造方法并使用

Class类中用于获取构造方法的方法

  • Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组

  • Constructor<?>[]getDeclaredConstructors():返回所有构造方法对象的数组

  • Constructor<T>getConstructor(Class<?>...parameterTypes):返回单个公共构造方法对象

  • Constructor<T>getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象

Constructor类中用于创建对象的方法

  • T newInstance(Object...initargs):根据指定的构造方法创建对象

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
​
public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取Class对象
        Class<?> c = Class.forName("util.Student");
        //调用Constructor<?>[]getDeclaredConstructors():返回所有构造方法对象的数组
        Constructor<?>[] cons = c.getDeclaredConstructors();
        for(Constructor con : cons)
        {
            System.out.println(con);
        }
        //参数:你要获取的构造方法的参数的个数和数据类型对应的字节码文件对象
        Constructor<?> con = c.getConstructor();
        //Constructor提供了一个类的单个构造函数的信息和访问权限
        //T newInstance(Object...initargs):根据指定的构造方法创建对象
        Object obj = con.newInstance();
        System.out.println(obj);
}
}
  • 基本数据类型也可以通过.class得到对应的Class类型

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
​
public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取Class对象
        Class<?> c = Class.forName("util.Student");
        //public Student(String name , int age)
        //Constructor<T>getConstructor(Class<?>...parameterTypes):返回单个公共构造方法对象
        Constructor<?> con = c.getConstructor(String.class,int.class);
        //基本数据类型也可以通过.class得到对应的Class类型
        Object obj = con.newInstance("xiaoli",19);
        System.out.println(obj);
}
}

  • public void setAccessible(boolean flag):值为true,取消访问检查

    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    ​
    public class Reflect {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
            //获取Class对象
            Class<?> c = Class.forName("util.Student");
            //private Student(String name)
            //Constructor<T>getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象
            Constructor<?> con = c.getDeclaredConstructor(String.class);
            //因为是私有方法,如果直接用newInstance返回对象会报错,所以需要暴力反射
            //public void setAccessible(boolean flag):值为true,取消访问检查
            con.setAccessible(true);
            Object obj = con.newInstance("xiaoli");
            System.out.println(obj);
    }
    }

反射获取成员变量并使用

Class类中用于获取成员变量的方法

  • Field[] getFields() : 返回所有公共成员变量对象的数组

  • Field[] getDeclaredFields() : 返回所有成员变量对象的数组

  • Field getField(String name) : 返回单个公共成员变量对象

  • Field getDeclaredField(String name) : 返回单个成员变量对象

Field类中用于给成员变量赋值的方法

  • void set(Object obj , Object value) : 给obj对象的成员变量赋值为value

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
​
public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //获取Class对象
        Class<?> c = Class.forName("util.Student");
        Field[] fields = c.getDeclaredFields();
        for(Field field : fields){
            System.out.println(field);
        }
        System.out.println("------------");
        Field addressField = c.getField("address");
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();
        addressField.set(obj,"湘潭");//给obj的成员变量addressField赋值为湘潭
        System.out.println(obj);
}
}
private java.lang.String util.Student.name
private int util.Student.age
public java.lang.String util.Student.address
------------
Student:name=null , age=:0 , address=:湘潭

  • 栗子

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
​
public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //获取Class对象
        Class<?> c = Class.forName("util.Student");
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();
        System.out.println(obj);
        //name
        Field nameField = c.getDeclaredField("name");
        nameField.setAccessible(true);//私有化
        nameField.set(obj,"小李");
        System.out.println(obj);
        //age
        Field ageField = c.getDeclaredField("age");
        ageField.setAccessible(true);//私有化
        ageField.set(obj,19);
        System.out.println(obj);
        //address
        Field addressField = c.getDeclaredField("address");
        addressField.setAccessible(true);
        addressField.set(obj,"湘潭");
        System.out.println(obj);
}
}
​
Student:name=null , age=:0 , address=:null
Student:name=小李 , age=:0 , address=:null
Student:name=小李 , age=:19 , address=:null
Student:name=小李 , age=:19 , address=:湘潭

  • 反射获取成员方法并使用

    Class类中用于获取成员你方法的方法

  • Method[] getMethods() : 返回所有公共成员方法对象的数组,包括继承的

  • Method[] getDeclaredMethod() : 饭hi所有成员方法对象的数组,包括不继承的

  • Method getMethod(String name,Class<?>...parameterTypes) : 返回单个公共成员方法对象

  • Method getDeclaredMethod(String name,Class<?>...parameterTypes) : 返回单个成员方法对象

Method类中用于调用成员方法的方法

  • Object invoke(Object obj,Object...args) : 调用obj对象的成员方法,参数是args,返回值是Object类型

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
​
public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //获取Class对象
        Class<?> c = Class.forName("util.Student");
        Method[] methods = c.getDeclaredMethods();
        for(Method method : methods)
        {
            System.out.println(method);
        }
        System.out.println("----------");
        //public void method1();
        Method m =c.getMethod("method1");//成员方法对象
        //获取无参构造方法创建对象
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();
        //在类或接口上提供有关单一方法的信息和访问权限
        //Object invoke(Object obj,Object...args) : 调用obj对象的成员方法,参数是args,返回值是Object类型
        //Object:返回值类型
        //obj:调用方法的对象
        //args:方法需要的参数,本次method1是无参的
        m.invoke(obj);//调用了obj对象的m的方法
        //Student s = new Student;
        //s.method1();
        }
}
public java.lang.String util.Student.toString()
public java.lang.String util.Student.getAddress()
public java.lang.String util.Student.getName()
public void util.Student.setName(java.lang.String)
private void util.Student.function()
public void util.Student.setAddress(java.lang.String)
public void util.Student.method1()
public java.lang.String util.Student.method3(java.lang.String,int)
public int util.Student.getAge()
public void util.Student.setAge(int)
public void util.Student.method2(java.lang.String)
----------
method
​

  • 栗子

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
​
public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //获取Class对象
        Class<?> c = Class.forName("util.Student");
        //Student s =new Student();
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();
        //s.method1()
        Method m1 = c.getMethod("method1");
        m1.invoke(obj);
        //s.method2()
        Method m2 = c.getMethod("method2", String.class);
        m2.invoke(obj, "小李");
        //s.method2()
        Method m3 = c.getMethod("method3", String.class, int.class);
        Object o = m3.invoke(obj, "小李", 19);
        System.out.println(o);
        //s.function()
        Method m4 = c.getDeclaredMethod("function");//私有方法
        m4.setAccessible(true);//暴力反射
        m4.invoke(obj);
    }
}
method
method小李
小李,19
function

  • 反射练习之越过泛型检查

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
​
public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
       //创建集合
        ArrayList<Integer> array = new ArrayList<Integer>();
        //array.add(10);
        //array.add(20);
        //array.add("hello");会报错
        Class<? extends ArrayList> c = array.getClass();
        Method m = c.getMethod("add",Object.class);
        m.invoke(array,"hello");
        m.invoke(array,"world");
        System.out.println(array);
    }
}
​
[hello, world]

  • 反射练习之运行配置文件指定内容

在创建的文件中写入指定的类和方法,用反射调用

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException, IOException {
      //Student s = new Student();
        //s.study();
        /*
        class.txt
        className=xxx
        methodNmae=xxx
         */
        //加载数据
        //Properties是一个Map体系的集合类,可以保存到流中或从流中加载
        Properties prop = new Properties();
        FileReader fr = new FileReader("untitled\\class.txt");
        prop.load(fr);
        fr.close();
        /*
        className = util.Student
        methodName = method1
         */
        String className = prop.getProperty("className");
        String methodName = prop.getProperty("methodName");
        //通过反射来使用
        Class<?> c = Class.forName(className);//文件中的类路径
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();
        Method m = c.getMethod(methodName);//method1
        m.invoke(obj);
​
    }
}
//新建文件,写入指定类和方法
className = util.Student
methodName = method1
//输出
method

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值