-------------------------------------------------android培训、java培训期待与您交流!----------------------------------
一、反射概念
Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class。
反射就是把Java类中的各种成分映射成相应的java类。
1.Class类代表Java类与各实例对象的分别?
1)对应各个类在内存中的字节码,如:Person类的字节码、ArrayList类的字节码等。
2)一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的对象来表示,这些对象显然具有相同的类型。
2.如何得到名个字节码对应的实例的对象(Class类型)
1)类名.class 例如:String.class
2)对象.getClass() 例如:new Date().getClass()
3)Class.forName("类名") 例如:Class.forName("java.util.Date");
3.九个预定义Class实例对象
int.class==Integer.TYPE
...
4.数组类型的Class实例对象
Class.isArray();//在源程序中出现的类型,都有各自的Class实例对象 如:int[] 、void...
System.out.println(int.class==Integer.TYPE);//true Integer.TYPE相当于基本类型int.class
//字节码Class对象只有一个(相对同一种类型)
System.out.println("Em".getClass()==String.class);
System.out.println("Em".getClass()==Class.forName("java.lang.String"));
System.out.println(int.class==Integer.class);//false 因为类型不同,字节码也不同
System.out.println(int.class.isPrimitive());//true 是基本类型
System.out.println(int[].class.isArray());//是不是数组类型字节码
二、Constructor的使用
Constructor类代表某个类中的一个构造方法
Class<?> className=Person.class;
//通过构造方法生存对象
//通过Class对象构造出一个构造对象
Constructor<?> con=className.getConstructor(new Class[]{String.class,int.class});
Person p=(Person)con.newInstance(new Object[]{"lebyd",19});
//构造一个无参构造方法对象
Person p=(Person)className.newInstance();//new一个实例
System.out.println(p);
//构造一个无参构造方法对象(难一点的写法)
Constructor<?> c=className.getConstructor(new Class[]{});
Object object=c.newInstance(new Object[]{});
三、Field类
Field类代表某个类中的一个成员变量
Person p=new Person();
Class<?> className=p.getClass();
//得到声明的成员变量
Field f=className.getDeclaredField("name");
f.setAccessible(true);//去除java访问的约束
f.get(p);//f不是对象身上的变量,而是类上的,要用它去取某个对象上对应的值
f.set(p, "123");//修改私有的成员
System.out.println(p.getName());
四、Method类
Method类代表某个类中的一个成员方法
//得到它的所有方法
Method[] method=className.getDeclaredMethods();
for(Method m:method)
{
System.out.println(m);
}
//通过类获取方法信息,方法名+方法类型的class
Method m=className.getMethod("toSay", new Class[]{String.class});
//方法对象的一个执行的方法,1.如果静态方法可以写Class类(或null)+参数2.如果不是就要通过对象+参数
//任返回值皆是Object类型,因为它不能确定
Object obj=m.invoke(className, "lebyd");
System.out.println(obj);
//数组参数的方法调用
public class InvokeArrs {
public static void main(String[] args) throws Exception {
Class<?> p=Person.class;
Method m=p.getMethod("say", String[].class);
//对数组进行打包
m.invoke(null, new Object[]{new String[]{"Em","Gm"}});
//封装成一个Object对象
m.invoke(p, (Object)new String[]{"Em","Gm"});
}
}
class Person
{
public static void say(String[] args)
{
for (String str : args) {
System.out.println(str);
}
}
}
五、数组与反射
public class IntAndStringArr {
public static void main(String[] args) {
int[] a1=new int[]{1,2,3};
int[][] a2=new int[][]{{1,2,3},{1,2,3}};
String[] a3=new String[]{"Em","Gm"};
//打印时把参数当作一个Object
System.out.println(a1);
System.out.println(a2);
System.out.println(a3);
//打印
/*[I@18a992f
* [[I@4f1d0d
* [Ljava.lang.String;@4f1d0d
*/
//Object[] obj=a1;
Object[] o=a2;
Object[] o1=a3;
System.out.println("---------------------");
System.out.println(Arrays.asList(a1));//这里把整个数组当个一个对象,因为里面是基本类型,不能转为Object
System.out.println(Arrays.asList(a2));//这里就把每个int[]当成一个Object了
System.out.println(Arrays.asList(a3));//把每个字符串当作为一个个Object,因为String继承Object
//输出
/*[[I@18a992f]
* [[I@150bd4d, [I@1bc4459]
[Em, Gm]*/
//打印任一对象
printObject(a1);
printObject("hello");
}
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);
}
}
}
-------------------------------------------------android培训、java培训期待与您交流!----------------------------------