一、反射Class 基本分析
反射的基石: Class 字节码
//得到这个类的字节码的实例对象3种
类名.class 如,System.class;
对象.class 如p1.getClass();
Class.for("java.lang.String"); //返回字节码
有9个预定义的Class实例对象
8个基本类型对应的,加1个void
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象
。 Class cls1 = void.class;
二、反射加强
反射就是把Java类中的各种成分映射成相应的java类。
---Class对象,类的组成部分: 成员变量,方法,构造方法,包等等信息。
---来获取其中的变量,方法,构造方法,修饰符,包等信息,用相应类的实例对象来表示,
它们是File、Method、Constructor、Package等等
class --->constructor --->new Object
Constructor类
---得到某个类所有的构造方法
Constructor[] constructor = Class.forName("java.lang.Sting").getConstructor();
----得到类中某一个构造方法 //获得方法时要用到类型
Constructor con1 = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
---创造实例对象 //获得调用方法时候用到上面相同类型
1. 通常方式 String str = new String(new StringBuffer("abc"));
2.反射方式 String str = (String)constructor.newInstance(new StringBuffer("abc"));
----Class.newInstance()方法
Sting obj = (String)Class.forName("java.lang.String").newInstance();
//该方法内部得到构造方法,然后用该构造方法创造实例对象。 //用到了缓存机制来保存默认构造方法的实例对象
成员变量的反射---Field类
ReflectPoint.java
//获得其值方法
//把对象上所有的String成员变量中的"b"换成"a"
main方法中
替换方法
Method类 ---代表某个类上的一个成员方法
----得到类中的某一个方法
Method charAt = Class.forName("java.lang.String").getMethod(charAt,int.class);
---调用方法
1. 通常方式 System.out.println(str.charAt(1));
2.反射方式 System.out.println(charAt.invoke(str,1));
//如果传递给Method对象的invoke()方法的一个参数为null,,,说明该Method对象对应的是一个静态方法
=================用反射方式执行某个类中的main方法
在类中再增加一个类
调用代码如下:
======数组的反射
Array工具类用于完成对数组的反射操作
//不能得到数组中的整个元素类型 ,,只能得到某一个元素类型
对数组进行反射
内省 --IntroSpector -->JavaBean--->特殊的Java类
JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)
PropertyDescriptor //import java.beans.PropertyDescriptor; 属性描述
在ReflectPoint中增加set,get方法
IntroSpectorTest.java
----采用遍历BeanInfo的所有属性方式来查找和设置某个ReflectPoint对象的属性. 调用了IntroSpector.getBeanInfo()方法 .封装了JavaBean的信息的。
Apache公司提供了beanutils工具包操作JavaBean,
Beanutils.getProperty(pt1,"x").getClass().getName();//返回String类型
BeanUtils.setProperty(pt1,"x","9"); //因为设置进去是以String. //如传到服务器一个int7是以字符串形式。
假设ReflectPoint增加一个 Date 属性 birthday = new Date();
BeanUtils.setProperty(pt1,"birthday.time","222"); //支持级联操作
Beanutils.getProperty(pt1,"birthday.time");
可以转换成map
map{age:33,name:heima} //java 7..
BeanUtils.setProperty(map,"birthday.time","222"); //map对象
另,PropertyUtils.setProperty(pt1,"x",9); //以int类型存储
------------------------反射的基本操作实例-------------------------------------------------
Person.java
测试类
=====
User.java
测试
=========调用构造方法
=========一个例子,用Hashtable存储对象======
====转换字符串INTEGER arraylist
final ArrayList<String> target = new ArrayList<String>();
target.add("sss");
target.add("bbb");
target.add("ccc");
Collection proxy = (Collection) Proxy.newProxyInstance(ArrayList.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler(){
public Object invoke(Object proxy, Method method,
Object[] values) throws Throwable {
if("add".equals(method.getName())){
return method.invoke(target, values);
}
return method.invoke(target, values);
}
});
proxy.add(12);
proxy.add(33);
for(Object o : proxy){
System.out.println(o.toString());
}
System.out.println(proxy.size());
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ClassMethod {
public static void main(String[] args) {
Person p = new Person();
try {
Method m = p.getClass().getMethod("println",null);
m.invoke(p, null);
m = p.getClass().getMethod("returns", null);
String s = (String) m.invoke(p, null);
System.out.println(s);
m = p.getClass().getMethod("returns", String.class);
s = (String) m.invoke(p, "hello");
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Person {
private String s = "s";
public void println(){
System.out.println("laiba");
}
public String returns(){
return "hh";
}
public String returns(String s){
return "sss"+s;
}
}