反射

来源:互联网 发布:网络信号大师破解版 编辑:程序博客网 时间:2024/06/11 22:23
反指的是可以利用对象找到对象的出处,
三种实例化操作:
1:调用Object类中的getcClass();
2:使用类.class()取得
3:调用Class类提供的方法,
public static Class<?> forName(String className) throws ClassNotFoundException
此时可以不使用Import语句导入一个明确的类,类名称用一个字符串进行描述的。

Class类中:取得一个构造:public Constructor<T> getConstructor(Class<?>... parameterTypes throws NoSuchMethodException,SecurityException
取得全部构造:public Constructor<?>[] getConstructors()throws SecurityException
以上两个方法都是 java.lang.reflect.AccessibleObject 类的对象,在这个类中提供有一个明确传递有参构造内容的实例化对象方法。
public T newInstance(Object... initargs)
throws InstantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
范例:明确调用有参构造;
public class custroct {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("com.reflect.Book");
Constructor<?>con = cls.getConstructor(String.class,double.class);
Object obj = con.newInstance("java" , 793.8);
System.out.println(obj);
}
}

结论:简单java 的开发之中,不管提供多少个构造方法,请至少保留无参构造;

一:利用反射实例化对象:
public T newInstance()throws InstantiationException, IllegalAccessException

在任何开发之中,new是造成耦合的最大元凶,一切的耦合都起源于new
所谓耦合是指在一个软件结构内不同模块之间互连程度的度量,
在工厂模式中,如果要增加一个类就要去修改工厂类,那么如果随时都可能增加子类呢?
工厂类要一直进行修改。
因为现在工厂类中的对象都是通过关键字new来实例化的,而new就成了所有问题的关键点,要想解决这一问题,我们只能够通过反射完成。
为了使用有参构造
取得一个构造:public Constructor<T> getConstructor(Class<?>... parameterTypes throws NoSuchMethodException,SecurityException
取得全部构造:public Constructor<?>[] getConstructors()throws SecurityException
以上两个方法都是 java.lang.reflect.AccessibleObject 类的对象,在这个类中提供有一个明确传递有参构造内容的实例化对象方法。
public T newInstance(Object... initargs)
throws InstantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
范例:明确调用有参构造;
public class custroct {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("com.reflect.Book");
Constructor<?>con = cls.getConstructor(String.class,double.class);
Object obj = con.newInstance("java" , 793.8);
System.out.println(obj);
}
}

结论:简单java 的开发之中,不管提供多少个构造方法,请至少保留无参构造;

package com.reflect;
interface Fruit{
public void eat();
}

class Apple implements Fruit{
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("eat apple");
}
}
class Orange implements Fruit{
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("eat orange");
}
}
class Factory{
public static Fruit getInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
Fruit f = null;
f = (Fruit) Class.forName(className).newInstance();
return f;
}
}
public class reflectTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Fruit f = Factory.getInstance("com.reflect.Apple");
f.eat();
}
}
此时的程序达到了解耦合的目的,而且可扩展性强;

二:反射类中的方法
类中的方法只有在产生一个实例化对象后可以调用,并且实例化对象方式有三种:
new() , 克隆, 反射。
取得类中的方法 :
取得指定方法:public Method getMethod(String name,Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException

取得全部方法:public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException,SecurityException

以上的两个操作返回的是 java.lang.reflect.Method类的对象,在这个类里面
重点关注一个方法,
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentExceptio InvocationTargetException
范例:反射调用方法:
package com.reflect;
import java.lang.reflect.Method;
public class getMethod {
public static void main(String[] args) throws Exception{
String filedName = "title";
Class<?>cls = Class.forName("com.reflect.Book");
Object obj = cls.newInstance();
Method setMet = cls.getMethod("set" + initcap(filedName), String.class);
Method getMet = cls.getMethod("get" + initcap(filedName));//此处还体现了统一命名的重要性
setMet.invoke(obj, "java");//等价于Book.set()传入java
System.out.println(getMet.invoke(obj));
}
public static String initcap(String str){
return str.substring(0,1).toUpperCase() + str.substring(1);
}
}
此时完全看不见具体的类型,也就是说可以用反射实现任意类的指定方法的作用;

三:反射成员
类中的属性一定要在本类实例化对象产生之后才可以分配空间。
在Class类里面,提供有取得成员的方法;

取得全部成员:
public Field[] getDeclaredFields()throws SecurityException
取得指定成员:
public Field getDeclaredField(String name) throws NoSuchFieldException,SecurityException
返回的类型为java.lang.reflect.Field

取得属性内容:
public Object get(Object obj)throws IllegalArgumentException,
IllegalAccessException
设置属性内容:
package com.reflect;
import java.lang.reflect.Field;
public class fieldTest {
public static void main(String[] args) throws Exception {
String filedName = "title";
Class<?> cls = Class.forName("com.reflect.Book");
Object obj = cls.newInstance();
Field titleField = cls.getDeclaredField(filedName);
titleField.setAccessible(true);
titleField.set(obj, "java");
System.out.println(titleField.get(obj));
}
}

在java.lang.reflect.AccessibleObject下面( JDK 1.7 之后改变)增加了一个Execuable子类
Execuable 下面继承了Construor , Method

Field 中提供了一个方法 ;
public void setExecuable (boolean flag)throws SecurityException 设置是否封装;



总结:实例化对象的方式又增加了一种;
对于简单java 类的定义更加清晰;
反射调用类结构只是一个开始











0 0
原创粉丝点击