由于要学习Spring框架,所以先补充一波对Java反射机制原理的理解。
遇到一个问题或者概念,第一步就是要知道它的基本定义,然后再探寻它是什么,怎么用。
什么是反射?
Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为Java 的反射机制。
以上的话通俗一点就是通过这个所谓的反射机制,我能够在程序运行的时候得到我所需要使用的对象的一切,唯一的条件就是我必须知道这个类的名称。一旦我知道这个类叫什么,我就可以向虚拟机提出我需要这个对象的请求,虚拟机会自动给你创建对象,而不用你再一个个new出来了。
回想之前的开发,我们若要获取一个类对象的属性或者方法,需要使用new一个对象的实例,然后调用该对象的方法。但是如果我们使用反射,我们就不需要通过new来获取方法,而是在运行中动态获取,从而降低随着需求的增加而修改源代码的情况发生(降低耦合)
这儿我使用例子来阐明反射的作用,便于更好的理解。
一般的代码会按照如下的格式:
interface Fruit {
public abstract void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("eat apple");
}
}
class Peach implements Fruit{
public void eat(){
System.out.println("eat peach");
}
}
class Factory{
public static Fruit getInstance(String fruitname){
Fruit f = null;
if ("Apple".equals(fruitname)){
f = new Apple();
}
if ("Peach".equals(fruitname)){
f = new Peach();
}
return f;
}
}
class Main{
public static void main(String[] args) {
Fruit f = Factory.getInstance("Peach");
if(f != null){
f.eat();
}
}
}
我们发现这样的工厂方法是存在弊端的,比如我现在想要添加一个水果Orange,那开发者必须到Factory类内部进行修改,添加if条件语句重新判断fruitname是不是Orange。随着时间的推移,这个Factory类会越来越臃肿,这对于代码的更新维护是非常致命的。那么如果我们想要避免这种问题,就可以尝试使用反射机制。接下来我将给大家演示反射机制的代码怎么写的,请各位读者仔细比较。
interface Fruit {
public abstract void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("eat apple");
}
}
class Peach implements Fruit{
public void eat(){
System.out.println("eat Peach");
}
}
class Factory {
public static Fruit getInstance(String classname){
Fruit f = null;
try{
f = (Fruit) Class.forName(classname).newInstance();
}catch (Exception e){
e.printStackTrace();
}
return f;
}
}
class Main{
public static void main(String[] args) {
Fruit f = Factory.getInstance("Peach");
if(f != null){
f.eat();
}
}
}
通过比较我们可以发现同一个Factory里的方法接收的是不一样的参数,不使用反射的则是接收fruitname,而使用反射的则是接收classname,也就是类名。这样我们只要给出具体类的名字,反射机制就会自动读取然后帮助你新建一个对象,不再需要使用new自己手动创建新的对象了。
那么哪里能体现出解除耦合呢?
我们可以观察上面的代码,如果我们需要添加新的水果子类,通过反射机制,我们不需要对Factory类中的代码进行修改,只需要直接添加水果子类然后记住类名即可。而原来的代码再添加子类的同时还需要修改Factory代码增加判断条件。看到这儿,反射的基本概念与使用应该就理解了。反射机制还有许多强大的地方,具体操作可以去参考API手册。
当然,反射也是存在一定的弊端的,虽然给我们代码带来了低耦合,但是使用起来开销非常大,所以这就告诫我们不要随意刻意使用反射机制,一定要把它用在最需要的地方。
初步了解了反射与工厂模式,我们就有基础去接触Spring框架中的IoC(控制反转)概念,Spring把这两个技术运用的非常恰当,可见不管多复杂多先进的框架都是从最基本最简单的概念开始的,技术的核心肯定是最简单的,这话就算为自己下一步学习Spring打打气啦: )