Class类:各个Java类属于同一类事物,描述这类事物的Java类名就是Class类。
Class.forName()作用:(1)如果已经在内存的话,不用再加载,直接返回字节码
(2)虚拟机里没有的话,用类加载器加载,返回给字节码
字节码对应的实例对象:(1)类名.class
(2)对象.getClass()
(3)Class.forName("类名"); 运行的时候可以临时放进来。
字节码:当源程序中用到类时,首先要从硬盘把这个类的那些二进制代码,一个类编译成class放在硬盘上以后,就是一些二进制代码,要把这些二进制代码加载到内存中里面来,再用这些字节码去复制出一个一个对象来。
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Boolean isPrimitive():判定指定的Class对象是否表示一个基本类型
Boolean isArray():判定此Class对象是否表示一个数组
getSuperClass():返回的父类
Constructor类
代表某个类的一个构造方法
(A)得到某个类所有的构造方法
Constructor[] con=Class.forName(“Java.lang.String”).getConstructor();
(B)得到某一个构造方法:
Constructor con=Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
(C)例:String str=new String(new StringBuffer("abc"));
用反射:Constructor con=String.class.getConstructor(StringBuffer.class);//选择哪个构造方法
String str=(String)con.newInstance(new StringBuffer("abc"));//传StringBuffer值
编译的时候他只知道是构造方法,不知道哪个类身上的构造方法。
运行的时候才知道对应的是哪个构造方法。
Field类
Class ReflectPiont
{
public int y;
private int x;
ReflectPoint(int y,int x){
This.y=y;
This.x=x;
}
}
Class FieldDemo
{
public static void main(String[] args){
ReflectPoint rp=new ReflectPoint(3,5);
Field y=rp.getClass().getField(“y”);
//到这儿,y指的不是具体对象的变量值,而是ReflectPoint里的变量
System.out.println(y.get(rp));
//所以get里要传递我指向的是哪一个对象,这时才会明确值
Field x=rp.getClass().getDeclaredField(“x”)
x.setAccessible(true);
//暴力反射
System.out.println(x.get(rp));
}
}
Method类:
代表某一个类中一个成员方法
(A)得到类中的某一个方法
Method m=Class.forName(“Java.lang.String”).getMethod(“charAt”,int.class);
(B)通常方法:System.out.println(str.charAt(1));
反射方法:Method m=str.getClass().getMethod(“charAt”,int.class);
m.invoke(str,1);
//如果传递给Method对象的Invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法。
jdk1.4和jdk1.5的invoke方法的区别:
jdk1.5:public Object invoke(Object obj,Object...args)
jdk1.4:public Object invoke(Object obj,Object[] args)
数组的反射
基本类型的一位数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当作Object[]类型使用。
Arrays.asList():处理int[]和String[]时的差异。
Array工具类用于完成对数组的反射操作。
怎么得到数组中的元素类型?
private static void printObject(Object obj) {
Class clazz = obj.getClass();
if(clazz.isArray()){ //判断是不是数组
int len = Array.getLength(obj);//用反射取出数组的长度
for(int i=0;i<len;i++){
System.out.println(Array.get(obj, i));//用反射取出数组的元素
}
}else{
System.out.println(obj);
}
}
----------
Object[] a=new Object[]{"a",1};
a[0].getClass().getName();
----------
反射的作用-〉实现框架功能
框架与框架要解决的核心问题
写程序时无法知道要被调用的类名,所以,在程序中无法直接New某个类的实例对象,用反射方法来做。
import java.io.FileInputStream;
import java.util.Collection;
import java.util.Properties;
public class ReflectTest {
public static void main(String[] args) throws Exception
{
//InputStream fs=new FileInputStream("config.properties");
//InputStream fs=ReflectTest.class.getClassLoader().getResourceAsStream("config.properties");
InputStream fs=ReflectTest.class.getResourceAsStream("resources/config.properties");
Properties props=new Properties();
props.load(fs);
String className=(String)props.getProperty("className");
fs.close();
Collection collections=(Collection)Class.forName(className).newInstance();
//Collection collections=new HashSet();
ReflectPoint rp1=new ReflectPoint(3,3);
ReflectPoint rp2=new ReflectPoint(4,3);
ReflectPoint rp3=new ReflectPoint(3,3);
collections.add(rp1);
collections.add(rp2);
collections.add(rp3);
collections.add(rp1);
System.out.println(collections.size());
}
}
InputStream getResourceAsStream(String name):返回读取指定资源的输入流
JavaBean
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
值对象:要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通向称之为值对象.
Beanutils工具包
在eclipse里,引入Beanutils工具包,等程序运行出错后再引入logging包
在前面内省例子的基础上,用Beanutils类先get原来设置好的属性,在将其set为一个新值。
-get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。
用PropertyUtils类先get原来设置好的属性,再将其set为一个新值。
-get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。
|
|