Java 反射

时间:2022-07-22
本文章向大家介绍Java 反射,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.使用反射创建对象

public class reflash {
    /*
     * 反射需要获取class类
     * 1.通过object的getclass文件获得
     * 2.通过类的。class获得
     * 3.通过Class的forName()获得
     */
    
     public static void main(String[] args) throws ReflectiveOperationException {
        //通过object类的getClass获得
//       Person p = new Person();
//       Class c = p.getClass();
         //通过类的。class方式获得
        // Class c = Person.class;
         //通过Class的forName()获得,
         //1.获得类的字节码文件class
         Class c = Class.forName("cn.bipt.reflash.Person");
         //2.获得构造器对象
         Constructor con = c.getConstructor(String.class,int.class,String.class);//里面传参是指构造方法的参数,可以获得的构造,不传参,无参构造
//       Constructor[] con1 = c.getConstructors();//获得所有的公共构造器对象
//       for (Constructor constructor : con1) {
//          
//      }
        // Constructor[] con2 = c.getDeclaredConstructors();//获取所有构造方法包括对象
         //3.调用newInstance()创建构造,返回person对象,使用Object接受
         Object obj = con.newInstance("张晓天",18,"陈建兵");//如果有参数里面即使参数
         System.out.println(obj);
         
    }

}

2.使用反射访问类的私有构造方法

public class reflash {
     
     public static void main(String[] args) throws ReflectiveOperationException {
        //1.获得字节码文件类Class
         Class c = Class.forName("cn.bipt.reflash.Person");
        //2.获得构造器对象
         Constructor con = c.getDeclaredConstructor(String.class);//获得私有的构造方法
         //3.调用newInstance()创建构造方法,并返回实体类对象与Object类中
         //值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
         con.setAccessible(true);
         Object obj = con.newInstance("张晓天");
         //访问
         System.out.println(obj);
        
    }

}

3.使用反射访问类的字段同时为字段赋值

public class reflash {
      
       public static void main(String[] args) throws Exception {
          //获取字节码文件Class
           Class c = Class.forName("cn.bipt.reflash.Person");
           //获取构造器
           Constructor con = c.getConstructor();
           Object obj = con.newInstance();//创建无参构造方法
           //获取字段
           Field  nameField = c.getDeclaredField("name");
           //设置字段值
           nameField.setAccessible(true);
           nameField.set(obj, "张晓天");
           //输出
           System.out.println(obj);
    }

}

4.使用反射调用方法

public class reflash {
    
     public static void main(String[] args) throws Exception {
        //获得字节码文件class
         Class c = Class.forName("cn.bipt.reflash.Person");
        //获得构造器
         Constructor con = c.getConstructor();
         //反射创建对象
         Object obj = con.newInstance();
         //获得方法
         Method showMethod = c.getMethod("show");
         showMethod.invoke(obj);
         //获得带参数方法
         Method setNameMethod = c.getMethod("setName",String.class);
         setNameMethod.invoke(obj, "张晓天");
         Method getNameMethod = c.getMethod("getName");
         Object name = getNameMethod.invoke(obj);
         System.out.println(obj+"----"+name);
  
    }

}

5.通过配值文件使用类方法

public class reflash {
    /*
     * 通过配值文件来使用类与方法
     */
    public static void main(String[] args) throws Exception {
        //加载配值文件
        Properties prop = new Properties();
        FileReader fr = new FileReader("Properties.properties");
        prop.load(fr);
        fr.close();
        //获得字节码文件Class
        Class c = Class.forName(prop.getProperty("className"));
        //获得构造器
        Constructor con = c.getConstructor();
        //新建构造方法
        Object obj = con.newInstance();
        //获得方法
        Method loveM = c.getMethod(prop.getProperty("classMethod"));
        loveM.invoke(obj);
        
                
    }

}

6.使用反射跳过java泛型的检测

public class ArrayListReflash {
    
     public static void main(String[] args) throws Exception {
         //创建集合对象
         ArrayList<Integer> array = new ArrayList<Integer>();
         
         //向集合中添加
         array.add(15);
        // array.add("zhang");//无法添加字符串,向集合中添加字符串,跳过java检测
        //获得class
         Class c = array.getClass();
         Method addM = c.getMethod("add",Object.class);
         addM.invoke(array, "张晓天");
         for (Object integer : array) {
            System.out.println(integer);
        }
    }

}

7.使用反射动态代理实现权限检测,和日志记录(java实现对接口的代理)

public interface UserDao {
    
    public abstract void login();
    
    public abstract void register();

}
public class UserDaoImpl implements UserDao{

    @Override
    public void login() {
    
        System.out.println("登录功能");
        
    }

    @Override
    public void register() {
    
        System.out.println("注册功能");
        
    }

}
public class MyInvocationHandler implements InvocationHandler{
    
    private  Object target;
    public MyInvocationHandler(Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("权限检测");
        Object object =method.invoke(target, args);
        System.out.println("日志记录");
        return object;//返回代理对象
    }

}
public class Test {

     public static void main(String[] args) {
          
          UserDao user = new UserDaoImpl();
                  //创建代理处理程序实例
          MyInvocationHandler handler2 = new MyInvocationHandler(user);
                  //获得代理对象
          UserDao userp = (UserDao)Proxy.newProxyInstance(user.getClass().getClassLoader(),user.getClass().getInterfaces(), handler2);
          userp.login();
          userp.register();
          
    }
}