【Java学习笔记】68:通过反射访问静态成员,越过泛型检查

标签: 反射 泛型 静态成员 静态变量 静态方法
19人阅读 评论(0) 收藏 举报
分类:

访问静态成员

静态成员的获取和普通的成员获取方法一致,但静态成员不需要在对象上执行(在反射中这样表述更合乎语法一些),所以不需要传入承载的对象,也就不需要获得类的对象。

package testReflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

//自定的一个类
class MyClass {
    private static double a1;// 静态成员变量

    // 主方法也是静态成员方法
    public static void main(String[] args) {
        System.out.println("静态方法执行了");
        System.out.println(Arrays.toString(args));
    }
}

// 在主类main方法中测试
public class Main {

    public static void main(String[] args) {
        try {
            // 加载类
            Class cls = Class.forName("testReflect.MyClass");

            // 从Class对象获取指定的成员方法
            Method mthd = cls.getDeclaredMethod("main", String[].class);
            // mthd.setAccessible(true);
            // 调用该成员方法,静态方法不需有载体对象因此传入null,还需传入参数并上转型到Object类型
            mthd.invoke(null, (Object) new String[] { "刘知昊", "大傻逼" });

            // 从Class对象获取指定的成员
            Field f1 = cls.getDeclaredField("a1");
            // 暴力反射,让这个私有静态成员变量可以越过权限检查
            f1.setAccessible(true);
            // 为成员变量设置值,无载体对象,还需传入值
            f1.set(null, 8.88);
            // 输出这个静态成员变量的值,于null无对象上(即表示静态成员变量)
            System.out.println("静态成员变量a1=" + f1.get(null));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

输出:

静态方法执行了
[刘知昊, 大傻逼]
静态成员变量a1=8.88

越过泛型检查

泛型是在编译期间起作用的,也就是在java类编译成class文件的过程中,会根据书写的泛型的具体类型,来对泛型类的对象的增删改查做类型检查。当编译完成,生成class文件之后,类型检查就不再起作用了,即做了泛型擦除使泛型中的实参不再生效。

反射通过class文件中的Class类的对象,复活这个类甚至对象,这个过程中该类或者该对象是没有经过编译的,而是从编译好的class文件中取出来的,所以用使用反射时也就避开了泛型检查

package testReflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

// 在主类main方法中测试
public class Main {
    private static ArrayList<String> al = new ArrayList<>();

    public static void main(String[] args) {
        // 获取其Class对象
        Class cls = al.getClass();

        try {
            // 获取其add方法,注意绕过了泛型的add参数完全是Object类型的
            Method mthd = cls.getDeclaredMethod("add", Object.class);
            // 添加一些其它类型的元素进去试试
            mthd.invoke(al, 100);
            mthd.invoke(al, true);
            mthd.invoke(al, 3.14);
            // 查看一下
            System.out.println(al.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

输出:

[100, true, 3.14]
查看评论

Java中通过反射越过泛型检查

要想Java通过反射越过泛型检查,你就得先明白,泛型是在什么时候起作用的。 泛型是在编译期间起作用的。在编译后的.class文件中是没有泛型的。所有比如T或者E类型啊,本质都是通过Object处理的。...
  • Marvel__Dead
  • Marvel__Dead
  • 2016-11-21 19:31:40
  • 966

java 反射之越过泛型检查

反射之前,我们知道在集合类中一旦指定了泛型的类型,则只能在该集合中用该类型。但是我们可以利用反射机制来越过泛型检查。比如说利用反射机制获取ArrayList中的add()方法,再调用add方法时,就会...
  • u010930785
  • u010930785
  • 2016-08-05 16:33:35
  • 887

利用反射调用方法,以及绕过泛型检查

比如知道一个类的对象,我们知道方法的名称,但是只有在运行的时候才知道调用哪个方法,这样只能用反射的方式调用了,拿List举例 List list = new ArrayList(); 但是我们只有...
  • qq_33802316
  • qq_33802316
  • 2017-07-29 11:20:02
  • 250

反射越过泛型检查

在博客《泛型--前世今生》中,我们了解到像如下: public class ArrayListTest { public static void main(String[] args) throws...
  • fightfaith
  • fightfaith
  • 2015-11-25 12:59:43
  • 958

利用反射越过泛型检查

1.问题描述 现在有一个List list = new ArrayList();如何在list中添加String数据??? 2.问题解决: 利用反射越过泛型检查,我们知道泛型其实就是在编译的时候检查,...
  • w2232097312
  • w2232097312
  • 2016-08-11 14:20:02
  • 240

通过反射越过泛型检查

通过反射越过泛型检查
  • wangyanming123
  • wangyanming123
  • 2016-05-09 19:51:07
  • 239

使用反射机制绕过泛型检查类型

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.uti...
  • qq_25343557
  • qq_25343557
  • 2017-07-24 15:54:07
  • 111

Java中通过反射获取泛型实例

通过反射获取泛型实例
  • jackielee_first
  • jackielee_first
  • 2016-11-27 17:54:57
  • 4758

反射-通过反射越过泛型检查

package cn.itcast.test; import java.lang.reflect.InvocationTargetException; import java.lang.reflec...
  • ZHOU_VIP
  • ZHOU_VIP
  • 2017-06-11 13:51:10
  • 135

反射_通过反射越过泛型检查

package cn.itcast.test; import java.lang.reflect.Constructor; import java.lang.reflect.Method; impo...
  • L1585931143
  • L1585931143
  • 2017-04-14 17:07:31
  • 260
    个人资料
    持之以恒
    等级:
    访问量: 14万+
    积分: 4715
    排名: 7695
    其它
    快毕业了。