反射(JAVASE)

75次阅读
没有评论

共计 4255 个字符,预计需要花费 11 分钟才能阅读完成。

                                                                                                                                                                                                   ## 什么是反射?

反射允许对封装类的字段,方法和构造函数的信息进行编程访问。(就是从类中拿东西)

例子:IDEA中的代码提示就是通过反射将类中的方法、形参获取出来。

需要从class字节码文件中获取class对象再解剖信息。

反射(JAVASE)

获取class对象的三种方式

  1. Class.forName("全类名");(全类名:包名+类名)。最为常用

    Class aClass = Class.forName("com.ouyu.Student");
  2. 类名.class。往往当作参数传递

    Class bClass = Student.class ;
  3. 对象.getClass();。有了这个类对对象时,才可以调用。

    Student s1 = new Student() ;
    Class aClass1 = s1.getClass();
    System.out.println(aClass1);

利用反射获取构造方法

Class类中用于获取构造方法的方法(Declared代表一种权限,表示能够访问到所有的对象)

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

Constructor[] cons = aClass.getConstructors();

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

Constructor[] cons = aClass.getDeclaredConstructors();

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

Constructor con = aClass.getConstructor(String.class);//参数与构造方法一致

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

Constructor con = aClass.geDeclaredtConstructor(String.class);//参数与构造方法一致

获取权限修饰符(getModifiers()

   Constructor cons = aClass.getDeclaredConstructor();
   int modifiers = cons.getModifiers();//public是1,private是2,具体其他参考文档

获取方法的参数(getParameters()

   Parameter[] parameters = cons.getParameters();
   for(Parameter e : parameters){
    System.out.println(e);
   }

Constructor类中用于创建对象的方法(newInstance(Object...initargs)

   con.setAccessible(true);//如果构造方法是私有的添加如下代码临时取消访问权限,暴力获取

   Constructor con = aClass.getDeclaredConstructor(String.class,int.class);
   Student ouyu = (Student)con.newInstance("ouyu", 16);

利用反射获取成员变量

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

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

Field[] fs = aClass.getFields();

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

Field[] fs = aClass.getDeclaredFields();

Field[] getField:返回单个公共成员变量对象

Field[] f = aClass.getField();

Field[] getDeclaredField:返回单个成 员变量对象

Field[] f = aClass.getDeclaredField();

获取权限修饰符(getModifiers()

Field f = aClass.getDeclaredField("name");
int modifiers = f.getModifiers();
System.out.println(modifiers);

获取成员变量的名字(getName()

Field f = aClass.getDeclaredField("name");
String s = f.getName() ;

获取成员变量的数据类型(getType()

Field f = aClass.getDeclaredField("name");
Class type = f.getType();

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

获取成员变量记录的值(get()

Student s1 = new Student("ouyu",12) ;
Field f = aClass.getDeclaredField("name");
f.setAccessible(true);////如果成员变量是私有的添加如下代码临时取消访问权限,暴力获取
String s = (String) f.get(s1);

修改对象里记录的值(set()

 f.set(s1,"luolei");

利用反射获取成员方法

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

Method[] getMethods:返回所有公共成员方法对象的数组(包含父类中所有的公共方法)

Method[] ms = aClass.getMethods();

Method[] getDeclaredMethods:返回所有成员方法对象的数组(不能并获取父类的,但是可以获取本类中私有的)

Method[] ms = aClass.getDeclaredMethods();

Method[] getMethod:返回单个公共成员方法对象(包含父类中所有的公共方法)

Method[] m = aClass.getMethod("name",String.class,int.class);//获取指定名字和参数的成员方法

Method[] getDeclaredMethod:返回单个成员方法对象(不能并获取父类的,但是可以获取本类中私有的)

Method[] m = aClass.getDeclaredMethod("name",String.class,int.class);//获取指定名字和参数的成员方法

获取成员方法的修饰符(getModifiers()

Method m = aClass.getDeclaredMethod("eat",String.class,int.class);
int modifiers = m.getModifiers();

获取方法抛出的异常

Method m = aClass.getDeclaredMethod("eat",String.class,int.class);
Class[] exceptionTypes = m.getExceptionTypes();

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

Object invoke(Object obj,Object...args):运行方法

参数1:用obj对象调用该方法
参数2:调用方法传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)

Method m = aClass.getDeclaredMethod("eat",String.class,int.class);
Student s = new Student() ;
m.setAccessible(true);//方法为私有是临时取消访问权限
System.out.println(m.invoke(s,"薯条",12)); ;//第一个参数调用方法的对象,后面的是传给方法的参数,此时我的这个方法的返回值是字符串,

反射的作用

  1. 获取一个类的所有信息,获取到了之后,再执行其他业务逻辑
  2. 结合配置文件,动态地创建对象并调用方法

练习

将对象的成员变量写入txt文件当中

public static void saveObject(Object obj) throws IllegalAccessException, IOException {
    //获取字节码文件
    Class classz = obj.getClass() ;
    //创建IO流
    BufferedWriter bw = new BufferedWriter(new FileWriter("src\\a.txt")) ;
    //获取成员变量
    Field[] fields = classz.getDeclaredFields() ;

    for(Field field : fields){
        field.setAccessible(true);
        String name = field.getName() ;
        Object value = field.get(obj) ;
        bw.write(name + " = " + value);
        bw.newLine();
    }
    bw.close();
}

利用反射动态创建对象

//读取配置文件
Properties prop = new Properties() ;
FileInputStream fis = new FileInputStream("prop.properties") ;
prop.load(fis);
fis.close();
String classname = (String) prop.get("classname");
String methodname = (String) prop.get("method");
//读取类的字节码文件
Class clazz = Class.forName(classname) ;
//获取构造方法
Constructor con = clazz.getDeclaredConstructor(String.class,int.class);
//用构造方法创建对象
Student s = (Student) con.newInstance("ouyu",12);
System.out.println(s);
//获取成员方法
Method method = clazz.getDeclaredMethod(methodname,String.class,int.class);
method.setAccessible(true);
//调用成员方法
method.invoke(s,"薯条",12) ;
classname = com.ouyu.Student
method = eat

通过配置文件动态的创建对象。

总结

反射(JAVASE)

正文完
 0
ouyu69
版权声明:本站原创文章,由 ouyu69 于2024-09-24发表,共计4255字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
文章搜索
评论(没有评论)