天真唔邪  

1、java反射机制(名词解释)

  在类的动态运行中,对于任意类,都能通过其路径获取类的所有属性和方法;这种动态获取类属性的功能叫做java的反射机制。

2、java反射机制的作用

  a、能够判断对象所属的类

  b、能够得到任意类的所有属性和方法

  c、能够构造任意类的对象,能够调用任意对象的方法

      d、生成动态代理(反射机制的动态代理 在后续的java动态代理章节 阐述)

3、Java API

  

//获取对象的路径名
Test test=new Test();
//取得类对象
Class<?> testClass=test.getClass();
Class<?> clazz =Class.forName("java类包的路径");
Class<?> clazz2=Test.class;
//获取对象的名字
String testClassName=testClass.getName();
//获取Class对象
Class<?> clazz =Class.forName("java类包的路径");
//取得父类
Class<?> parentClass =Clazz.getSuperclass();
//取得类的所有接口
Class<?> infes[] =Clazz.getInterfaces();
//实例化类对象
Class<?> class1=ClassforName("com.demo.User");
User user=(User)class1.newInstance();
//取得类的所有构造器
Constructor constructors[]=class1.getConstructors();
//获取类的所有方法
Method method[] =class1.getMethods();
//调用类中的方法
Method method=class1.getMenthod("method1");
menthod.invoke(class.newInstance());
//获取属性值
Field[] fields=class1.getDeclaredFields();//本类
Field[] fields=class1.getFields();//取得实现的接口或者父类的属性
//取得权限类型
int mo =fields[0].getModifiers();
String priv=Modifier.toString(mo);
//取得属性类型
Class<?> type=field[0].getType();
String typeName=type.getName();
//操作属性
Object obj=class1.newInstance();
class1.getDeclaredFields("xx属性").setAccessible(true).set(obj,"xx新属性");

 

 4、应用实例

package com.demo;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class TestRefect {
    public static void main(String[] args) throws Exception, NoSuchMethodException {
        ArrayList list=new ArrayList();
        Class<?> clazz=list.getClass();
        Method method=clazz.getMethod("add", Object.class);
        method.invoke(list, "反射");//运行方法  对象 值
        System.out.println(list.get(0));
    }

}

//获得并修改数组的信息
package
net.xsoftlab.baike; import java.lang.reflect.Array; public class TestReflect { public static void main(String[] args) throws Exception { int[] temp = { 1, 2, 3, 4, 5 }; Class<?> demo = temp.getClass().getComponentType(); System.out.println("数组类型: " + demo.getName()); System.out.println("数组长度 " + Array.getLength(temp)); System.out.println("数组的第一个元素: " + Array.get(temp, 0)); Array.set(temp, 0, 100); System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0)); } }

修改数组的大小

package net.xsoftlab.baike;
import java.lang.reflect.Array;
public class TestReflect {
    public static void main(String[] args) throws Exception {
        int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int[] newTemp = (int[]) arrayInc(temp, 15);
        print(newTemp);
        String[] atr = { "a", "b", "c" };
        String[] str1 = (String[]) arrayInc(atr, 8);
        print(str1);
    }
    // 修改数组大小
    public static Object arrayInc(Object obj, int len) {
        Class<?> arr = obj.getClass().getComponentType();
        Object newArr = Array.newInstance(arr, len);
        int co = Array.getLength(obj);
        System.arraycopy(obj, 0, newArr, 0, co);
        return newArr;
    }
    // 打印
    public static void print(Object obj) {
        Class<?> c = obj.getClass();
        if (!c.isArray()) {
            return;
        }
        System.out.println("数组长度为: " + Array.getLength(obj));
        for (int i = 0; i < Array.getLength(obj); i++) {
            System.out.print(Array.get(obj, i) + " ");
        }
        System.out.println();
    }
}

将反射用于工厂模式

package net.xsoftlab.baike;
interface fruit {
    public abstract void eat();
}
class Apple implements fruit {
    public void eat() {
        System.out.println("Apple");
    }
}
class Orange implements fruit {
    public void eat() {
        System.out.println("Orange");
    }
}
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;
    }
}
/**
 * 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。
 * Java 工厂模式可以参考
 * http://baike.xsoftlab.net/view/java-factory-pattern
 * 
 * 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。
 * 
 * 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。
 * 
 * java 读取 properties 配置文件 的方法可以参考
 * http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file
 * 
 * @author xsoftlab.net
 */
public class TestReflect {
    public static void main(String[] args) throws Exception {
        fruit f = Factory.getInstance("net.xsoftlab.baike.Apple");
        if (f != null) {
            f.eat();
        }
    }
}

 

posted on 2017-03-30 16:38  天真唔邪  阅读(559)  评论(0编辑  收藏  举报