Java的类的反射机制和运用浅析

java的反射机制可以说是java开发框架的灵魂所在。
在本篇博客中,我会结合别人大牛博客上所说和自己的理解浅谈反射机制的理解和IOC和反射机制的关系。

反射机制的概念

主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息。
反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!
类中有什么信息,利用反射机制就能可以获得什么信息,不过前提是得知道类的名字。

反射机制的作用

1.在运行时判断任意一个对象所属的类;
2.在运行时获取类的对象;
3.在运行时访问java对象的属性,方法,构造方法等

反射机制的优缺点

首先要搞清楚为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念。

静态编译:在编译时确定类型,绑定对象,即通过。

动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。

反射机制的优点:可以实现动态创建对象和编译,体现出很大的灵活性(特别是在J2EE的开发中它的灵活性就表现的十分明显)。通过反射机制我们可以获得类的各种内容,进行了反编译。对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。
 
反射机制的缺点:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它 满足我们的要求。这类操作总是慢于只直接执行相同的操作。

简单的反射运用Demo

首先创建一个水果类

public class Fruit {
    private String name;//名字
    private int weight;//重量
    public Fruit(){

    }
    @Override
    public String toString(){
        return "Fruit [\n name = " + name + ",\n weight = " + weight + "\n]";
    }
}

然后创建ReflectDemo主类:

import java.lang.reflect.Field;

public class ReflectDemo {
    public static void main(String[] args){
        Class<?> fruitClass = Fruit.class;
        try {
            Object object = fruitClass.newInstance();
            Field[] fields = fruitClass.getDeclaredFields();
            System.out.println("Fruit所有属性:");
            for(Field field : fields){
                System.out.println(field);
            }
            Field field = fruitClass.getDeclaredField("name");
            field.setAccessible(true);
            field.set(object,"苹果");
            Field field2 = fruitClass.getDeclaredField("weight");
            field2.setAccessible(true);
            field2.set(object, 18);
            System.out.println("修改后的Fruit值:");
            System.out.println((Fruit)object);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

运行结果:
这里写图片描述
解释一下以上代码:
class<?>是一个泛型,具体的解释这里就不写了。
.newInstance()是实例化的一个方法,与new不同方法只能实例化无参的构造方法。
Field是一个属性类。
.setAccessible是获得修改的权限,默认是false.
通过这种方式就可以来访问和修改类中private的属性值了,是不是很神奇。

工厂模式和运用了反射机制的工厂模式

未用反射机制的工厂模式
首先创建Fruit接口

interface Fruit {
    public abstract void eat();
}

然后分别用两个实体类来实现这个接口

public class Apple implements Fruit{
    public void eat() {
        System.out.println("Apple");
    }
}

public class Orange implements Fruit{
    @Override
    public void eat() {
        System.out.println("Orange");   
    }

}

最后创造出工厂类:

public class Factory {
    public static Fruit getInstance(String fruitName) {
        Fruit f = null;
        if("Apple".equals(fruitName)) {
            f = new Apple();
        }
        if("Orange".equals(fruitName)) {
            f = new Orange();
        }
        return f;
    }

}

主类运行:

public class Main {

    public static void main(String[] args) {
        Fruit f = Factory.getInstance("Orange");
        f.eat();
    }

}

这样创建的工厂类,一旦有新的水果产生就要去改工厂类里面的方法,非常的麻烦,但是运用到了反射机制后,当新增水果的时候就能不需要去更改工厂类的方法。
改动后的工厂类:

public class Factory {
    public static Fruit getInstance(String fruitName) {
        Fruit fruit = null;
        try {
            fruit = (Fruit)Class.forName(fruitName).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return fruit;
    }
}

代码解释:

在这里通过反射机制传递类名来进行实例化。这样就降低了耦合,方便了代码的扩展。
不过在Main类中要加一个

if(f != null) {
            f.eat();
        }

因为f有可能为空。
以上就是我的类的反射机制的和运用的简单理解,如果有更深或者有误的,还请多多指出,谢谢,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值