关于Java反射的知识总结

反射

1.获取Class对象的方法

public class Test {
    public static void main(String[] args) {
        //通过类获取Class对象
        Class clazz1 = Student.class;
        //通过对象获取Class对象
        Student s = new Student(18, 0);
        Class clazz2 = s.getClass();
        //通过forName静态方法
        try {
            Class clazz3 = Class.forName("cn.it.ref.Student");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

2.获取构造器

方法 描述
Connstructor getConstructor(Class...paramterTypes) 获取Class对象对应类的带指定参数列表的public构造器
Connstructor getContructors() 获取Class对象对应类的所有public构造器
Connstructor getDeclaredConstructor (Class...paramterTypes) 获取Class对象对应类的带指定参数列表的构造器,与访问修饰符无关
Connstructor getDeclaredConstructors() 获取Class对象对应类的所有构造器,与访问修饰符无关
2.1示例
public class Test2 {
    
    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        
        Class clazz = Student.class;
        
        //获取public修饰的构造方法
        Constructor[] c1 = clazz.getConstructors();
        
//      for (Constructor constructor : c1) {
//          System.out.println(constructor);
//      }
        //获取所有构造方法,与访问修饰符无关
        Constructor[] c2 = clazz.getDeclaredConstructors();
//      for (Constructor constructor : c2) {
//          System.out.println(constructor);
//      }
        //获取指定的public修饰的构造方法
        Constructor c = clazz.getConstructor(int.class,double.class);
        System.out.println(c);
        
//      Constructor tempc = clazz.getConstructor(double.class);
        
        //获取指定参数的构造器,与访问修饰符无关
        Constructor construct1 = clazz.getDeclaredConstructor(double.class);
        System.out.println(construct1);
        
        Constructor construct2 = clazz.getDeclaredConstructor();
        
        System.out.println(construct2);
    }
    
}

3.获取成员方法

方法 描述
Method getMethod(String name,Class...paramterTypes) 获取指定名称和参数类型class对象的public修饰方法
Method[] getMethods() 获取所有public修饰的成员方法以及继承的方法,包括静态方法
Method getDeclaredMethod(String name,Class...paramterTypes) 获取指定名称和参数类型class对象的方法,与访问修饰符无关
Method[] getDeclaredMethods() 获取自身声明的所有成员方法,与访问修饰符无关
3.1示例
public class MethodTest {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //获取Class对象
        Student s = new Student(0);
        Class clazz = s.getClass();
        //获取public修饰的方法包含父类public修饰的方法
        Method[] methods = clazz.getMethods();
        
//      for (Method method : methods) {
//          System.out.println(method);
//      }
        //获取自身声明的所有方法,与访问修饰符无关
        Method[] methods2 = clazz.getDeclaredMethods();
        
//      for (Method method : methods2) {
//          System.out.println(method);
//      }
        //获取指定参数的public修饰的成员方法
//      Method method = clazz.getMethod("newObject");
//      System.out.println(method);
        //获取指定参数的自身声明的方法,与访问修饰符无关
        Method method2 = clazz.getDeclaredMethod("newObject", int.class);
//      System.out.println(method2);
//      method2.setAccessible(true);
//      method2.invoke(s,2);
        Method method3 = clazz.getDeclaredMethod("makeMoney");
        method3.invoke(s);
        Method method4 = clazz.getDeclaredMethod("sleep",String.class);
        method4.invoke(null,"蔡老师");
    }
}

4.获取成员变量

方法 描述
Field getField(String name) 获取指定名称的public修饰的成员变量
Field[] getFields() 获取所有的public修饰的成员变量,包括从父类继承的成员变量
Field getDeclaredField(String name) 获取指定名称的成员变量,与访问权限无关
Field[] getDeclaredFields() 获取所有的成员变量,与访问修饰符无关
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        Son s = new Son();
        Class clazz = s.getClass();
        //获取自身和父类public修饰的成员变量
        Field[] fields = clazz.getFields();
//      for (Field field : fields) {
//          System.out.println(field);
//      }
        //获取自身声明的成员变量,与访问修饰符无关
        Field[] fields2 = clazz.getDeclaredFields();
//      for (Field field : fields2) {
//          System.out.println(field);
//      }
        //根据指定名称获取自身和父类public修饰的成员变量属性
        Field f1 = clazz.getField("age");
        f1.setInt(s, 10);
        System.out.println(s.age);
        
        Field f3 = clazz.getField("name");
        f3.set(s, "张三");
        System.out.println(s.name);
        //根据指定名称获取属性,与访问修饰符无关
        Field f2 = clazz.getDeclaredField("width");
        System.out.println(f2);
        f2.setAccessible(true);
        f2.setInt(s, 100);
        System.out.println(s.getWidth());
        
    }

5.获取注解

6.Method对象方法

方法 描述
invoke(Object obj,Object...obj) 调用对象方法
setAccessible(boolean flag) 设置私有方法可访问

7.实例化对象

方法 描述
clazz.newInstance() 只能调用默认无参构造方法
Constructor.newInstance(Object..obj) 调用对应的构造方法
7.1示例
public class NewInstance {
    
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        
        Class clazz = Class.forName("cn.itlaobing.ref2.Student");
        Constructor c = clazz.getDeclaredConstructor(int.class);
        c.setAccessible(true);
        //利用构造方法newInstanc方法
        Student s = (Student)c.newInstance(18);
        
        System.out.println(s.getAge());
        //利用class对象newInstance,调用默认无参构造
//      Student s2 = (Student) clazz.newInstance();
//      System.out.println(s2.getAge());
    }
}

8.作业实例

1.使用反射创建FileInputStream以及BufferedInputStream读取某个文件,并利用反射创建
FileOutputStream和BufferedOutputStream对象,将文件写入到E://File(如果使用File对象)
也必须使用反射创建对象

package com.itlaobing.z0830;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@SuppressWarnings("all")
public class ReflectFileTest {

    public static void main(String[] args) {
        // 获取FileInputStream类信息
        Class clazz1 = FileInputStream.class;
        // 获取BufferedInputStream类信息
        Class clazz2 = BufferedInputStream.class;
        // 获取FileOutputStream类信息
        Class clazz3 = FileOutputStream.class;
        // 获取BufferedOutputStream类信息
        Class clazz4 = BufferedOutputStream.class;

        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        Method bisClose = null;
        Method bosClose = null;
        try {
            // 获取FileInputStream类构造方法
            Constructor constructor = clazz1.getDeclaredConstructor(String.class);

            // 通过构造器.newInstance创建对象
            fis = (FileInputStream) constructor.newInstance("D:/1/Menu.java");

            // 获取BufferedInputStream类构造方法
            Constructor constructor2 = clazz2.getDeclaredConstructor(InputStream.class);

            // 通过构造器.newInstance创建对象
            bis = (BufferedInputStream) constructor2.newInstance(fis);

            // 获取BufferedInputStream的read()方法
            // Method read = clazz2.getMethod("read");

            // 获取BufferedInputStream的read(byte[] b)方法(调用的FileinputStream的read(byte[] b))
            Method read = clazz2.getMethod("read", byte[].class);

            // 获取BufferedInputStream的close()方法
            bisClose = clazz2.getDeclaredMethod("close");

            // 获取FileOutputStream类构造方法
            Constructor constructor3 = clazz3.getDeclaredConstructor(String.class);

            // 通过构造器.newInstance创建对象
            fos = (FileOutputStream) constructor3.newInstance("D:/1/File/Menu.java");

            // 获取BufferedOutputStream类构造方法
            Constructor constructor4 = clazz4.getDeclaredConstructor(OutputStream.class);

            // 通过构造器.newInstance创建对象
            bos = (BufferedOutputStream) constructor4.newInstance(fos);

            // 获取BufferedOutputStream的write()方法
            // Method write = clazz4.getMethod("write", int.class);

            // 获取BufferedOutputStream的write(byte[] b)方法(调用的FileOutputStream的write(byte[] b))
            Method write = clazz4.getMethod("write", byte[].class);

            // 获取BufferedOutputStream的close()方法(其实获得的是父类FilterOutputStream的close()方法)
            bosClose = clazz4.getMethod("close");

            // 读写文件
            int i = 0;
            // 利用read.invoke获得read()方法,利用write.invoke获得write(int i)方法
            // while ((i = (int) read.invoke(bis)) > -1) {
            // write.invoke(bos, i);
            // }

            byte[] b = new byte[1024];
            // 利用read.invoke获得read(byte[] b )方法,利用write.invoke获得write(byte[] b)方法
            while ((i = (int) read.invoke(bis, b)) > -1) {
                write.invoke(bos, b);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } finally {
            try {
                bisClose.invoke(bis);
                bosClose.invoke(bos);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
}

你可能感兴趣的:(关于Java反射的知识总结)