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有可能为空。
以上就是我的类的反射机制的和运用的简单理解,如果有更深或者有误的,还请多多指出,谢谢,