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(); } } }

浙公网安备 33010602011771号