为了账号安全,请及时绑定邮箱和手机立即绑定

java高级开发 反射基本详解

标签:
Java

反射作为java高级的一个知识点。虽然一般开发情况下不会用到,但是也算是必须知道的知识点
如下则是java的反射包 java.lang.reflect
在开始我们建立一个父类 Anmion (名字我瞎起的,只作为展示代码效果来看,主要测试某些方法):

public class Anmion {

    protected int aaa;

    private int bbb;

    public int ccc;

    public int getAaa() {
        return aaa;
    }

    public void setAaa(int aaa) {
        this.aaa = aaa;
    }

    public int getBbb() {
        return bbb;
    }

    public void setBbb(int bbb) {
        this.bbb = bbb;
    }

    public int getCcc() {
        return ccc;
    }

    public void setCcc(int ccc) {
        this.ccc = ccc;
    }

    @Override
    public String toString() {
        return "Anmion{" +
                "aaa=" + aaa +
                ", bbb=" + bbb +
                ", ccc=" + ccc +
                '}';
    }
}

建立好了父类,我们再建立子类,以便于继承父类

public class People extends Anmion{

    private String name;

    private int sex;

    public int old;

    public People(String name, int sex, int old) {
        this.name = name;
        this.sex = sex;
        this.old = old;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getSex() {
        return sex;
    }
    public void setSex(int sex) {
        this.sex = sex;
    }
    public int getOld() {
        return old;
    }
    public void setOld(int old) {
        this.old = old;
    }
    private void showName(){
        System.out.println("sfdsa" + name);
    }
    public void showOld(){
        System.out.println("sfdsa"+old);
    }
    @Override
    public String toString() {
        return super.toString()+"People{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", old=" + old +
                '}';

    }
}

如上两个类,我都将tostring()方法重新写了一下,目的在于,方便测试(细节就不要在意了,你也可以不重写)

一般情况下,你想创建一个对象,你会采用,如下策略

People people = new People();

为了测试反射,我们将改变产出的方式:
如下

Class clazz = Class.forName("People");
People people = (People) clazz.newInstance();

Class.forName 在jvm中查找并加载该class,
注意:以上的方式是无参数构造,如果没有无参构造器,则不能使用如上方式产出people

有参数构造方式

Class clazz = Class.forName("People");
Constructor constructor = clazz.getConstructor(String.class, int.class,int.class);

            People people = (People) constructor.newInstance("test", 1,2);

还有一点要注意 int.class 和Integer.class 是不同的两个东西。

如下则是获取字段和方法的代码,看我一一介绍一下:

clazz.getName():获取该class的名字。
clazz.getDeclaredFields():获取该class里的字段(包括public private protected)
clazz.getFields():获取该class里的字段(仅仅包括 public 继承的public)
clazz.getMethods():获取该class里方法(仅仅包括public 继承的public)
clazz.getDeclaredMethods():获取该class里的字段(包括public private protected)

于是我们就可以进行一些不可告人的事情了

//遍历该类的所有字段
for(Field field:getDeclaredFields()){
                field.setAccessible(true);
                Class t = field.getType();

                if(t.isAssignableFrom(String.class)){
                    System.out.println( field.get(people));
                }else if(t.isAssignableFrom(int.class)){
                    System.out.println( field.getInt(people));
                }
            }

如上代码我解释一下field.setAccessible(true); 设置true的作用很大,如果不设置的话,是不能够访问受保护的字段和私有字段,(同样方法也是)
isAssignableFrom是个比较两个类型是否相同,或者是否是某个类的子类,与 instanceof 作用差不多,但是是比较类型的。
如果类型相同,毋庸置疑就能拿出该类的值,我只是复杂的写了一下,简单写法如下:

for(Field field:getDeclaredFields()){
 field.setAccessible(true);
System.out.println( field.get(people));
}

设置字段的值:

//循环去设置值
for(Field field:fields){
                String n = field.getName();

                System.out.print(n);

                if(n.equalsIgnoreCase("name")){
                    field.set(people, "嚣张");
                }
                if(n.equalsIgnoreCase("sex")){
                    field.set(people,14231);
                }
                if(n.equalsIgnoreCase("old")){
                    field.set(people,32);
                }
            }
//直接设置值

Field f1 = clazz.getDeclaredField("sex");
            f1.setAccessible(true);
            f1.setInt(people,14);

获取方法也是一样:如下代码

 Method[] methods = clazz.getDeclaredMethods();

            for(Method method:methods){
                method.setAccessible(true);
                System.out.println(Modifier.toString(method.getModifiers())+" "+ method.getReturnType().getName() +" " + method.getName());
            }
            for(Method m:methods){
                String n = m.getName();

                if(n.equalsIgnoreCase("setName")){
                    if(m.getParameterTypes().length == 1){
                        m.invoke(people,"呢");
                    }
                }
            }
            System.out.println(people.toString());
//直接设置名字
            Method m1 = clazz.getMethod("setName", String.class);
            m1.invoke(people, "赵文");

解释如下
Modifier.toString(method.getModifiers())是获取当前方法的类型,如public private
method.getReturnType().getName()获取方法返回值类型名

如上就是java反射的基本内容,谢谢

点击查看更多内容
5人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
81
获赞与收藏
3602

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消