= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* 作用:
*) 动态编程
可以用配置文件,
配置使用的类,或调用的方法
*) 获得一个类的信息
*) 类名
*) 成员变量
*) 构造方法
*) 方法
*) 反射创建对象
*) 反射调用对象的成员
* “类对象”
*) 理解成“图纸”对象
*) 任何类型,都有类对象
*) 每个类型的类对象只有唯一的一个
获得一个类的类对象
----------------------------------------
1) Class<Student> c = Student.class
2) Class<Student> c = Class.forName("tarena.day2202.Student")
指定类型名称,获得“类对象”
3) Object s = 获得一个对象
Class c = s.getClass();//获得一个对象的真实类型的“类对象”
Class 方法
--------------------------------------------------
*) 获得类的信息
c.getPackage().getName(); 包名
c.getName(); 完整类名
c.getSimpleName(); 类名(不含包名)
c.getFields(); 有权访问的成员变量(含继承的成员变量)
c.getDeclaredFields(); 所有成员变量(含私有,但不含继承的成员)
c.getField(name); 指定名称的成员变量
c.getDeclaredField(name); 指定名称的成员变量(含私有)
c.getConstructors(); 有权访问的构造方法
c.getDeclaredConstructors(); 所有构造方法(含私有)
c.getConstructor(parameterTypes); 指定参数类型的构造方法
c.getMethods(); 有权访问的方法(含继承的方法)
c.getDeclaredMethods(); 所有方法(含私有,但不含继承的方法)
c.getMethod(name, parameterTypes);指定方法名和参数列表的方法
*) 反射创建对象
c.newInstance() 执行无参构造方法创建对象
Constructor con = 得到其中一个构造方法
Object obj = con.newInstance(参数数据);//执行有参构造方法创建对象
*) 访问成员变量
Object obj = ...
Class c = ...
Field f = c.getDeclaredField(变量名);
f.setAccessible(true);//使私有成员可访问
f.getModifiers(); //修饰符
f.getType();//类型
f.getName();//变量名
f.set(obj, 值); //为 obj 的变量赋值
f.get(obj); //访问 obj 的变量值
示例代码:
public static void main(String[] args) throws Exception { String className="java.lang.Integer"; //String className="java.util.ArrayList"; //String className="java.util.Date"; System.out.println(className); Class c=Class.forName(className); Object a = null; Object b = null; try { //尝试执行无参构造方法,创建对象 a=c.newInstance(); System.out.println("a对象已创建"); } catch (Exception e) { System.out.println("没有无参构造方法"); } try { //尝试执行接收int 参数的构造方法,创建对象 //首先获得这个构造方法定义信息的封装对象 Constructor con=c.getConstructor(int.class); b=con.newInstance(10); System.out.println("b对象已创建"); } catch (Exception e) { System.out.println("没有int参数的构造方法"); } System.out.println("a对象:"+a); System.out.println("b对象:"+b); //访问成员变量 int value Field f=c.getDeclaredField("value"); f.setAccessible(true); //从b对象访问 value 的值 Integer v=(Integer)f.get(b); System.out.println(v); //为b对象中的value 变量赋值 f.set(b, 0); System.out.println(b); } |
*) 调用方法
Object obj = ...
Class c = ...
Method m =
c.getDeclaredMethod(方法名, 参数类型列表);
m.setAccessible(true);
//通过 obj 对象调用方法
Object returnValue = m.invoke(obj, 参数值)
示例代码:
public static void main(String[] args) throws Exception { String className="java.util.GregorianCalendar"; Class c =Class.forName(className); Object obj=c.newInstance(); //调用 getTime() 方法 Method m=c.getMethod("getTime"); Object returnValue=m.invoke(obj); System.out.println(returnValue); } |
附:反射动态编程 代码
1. 配置文件 config.xml
<config> <activity name="tarena.day2203.MainActivity"/> <Button onClick="doClick"/> </config> |
2. Activity 类
public class Activity { public void onCreate(){ } } |
3. MainActivity 类
public class MainActivity extends Activity { @Override public void onCreate() { System.out.println("MainActivity.onCreate"); } public void doClick(View view){ System.out.println("MainActivity.doClick"); } } |
4. View 类
public class View {
} |
5. Button
public class Button extends View{ } |
6. 测试类
import java.lang.reflect.Method; import java.util.Scanner; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader;
public class Test1 { public static void main(String[] args) throws Exception { String path=Test1.class.getResource("/config.xml").getPath(); Document doc=new SAXReader().read(path); Element cfg=doc.getRootElement(); String s1=cfg.element("activity").attributeValue("name"); //System.out.println(s1); Class c1=Class.forName(s1); Activity a=(Activity)c1.newInstance(); a.onCreate(); Element e=cfg.element("Button"); if(e!=null){ String s2=e.attributeValue("onClick"); System.out.println("请点击按钮(回车点击按钮)"); new Scanner(System.in).nextLine(); Button btn=new Button(); Method m=c1.getMethod(s2,View.class); m.invoke(a, btn); } } } |