一、反射
java中,对于任意一个类,都能知道其中的属性和方法,通过其中的对象可以得到该类中的属性和方法,从而调用该类中的属性和方法,将类进行解剖,即为通过特定对象反映出来的类中的属性和方法,并进而进行调用。
二、反射的方法
一个Class:字节码
一个Method:方法
一个Construtor:构造方法
一个Field:数据成员
Class:得到该类的字节码文件,所谓字节码文件,即为类创建时期家在进入内存的二进制文件,当该二进制文件加载进入内存之后,便用该字节码去复制成一个个的对象。
得到该字节码文件的额三种方式:
String a=new String();
Class cls1=a.getClass();//方法1、利用对象调用getClass方法得到字节码文件;
Class cls2=String.class;//方法2、用类中的静态属性class来直接得到;
System.out.println(cls1==cls2);
System.out.println(cls1);
Class cls3=Class.forName("java.lang.String");//方法3、用Class工具类得到,Class.forName("包名.类名");
Method:得到类中的方法,用private修饰的成员方法可以通过Accessible去强行获取,如下
Person p=new Person(23,"hahh");
Class p1=Person.class;
Method method=p1.getMethod("hehe");
Object o=method.invoke(p);
System.out.println(o);
Constructor:得到构造方法,利用Constructor类来创建类实例的好处是可以指定构造函数,而Class类只能利用无参构造函数创建类实例对象。
Constructor con=Person.class.getConstructor(int.class,String.class);
Person p2=(Person)con.newInstance(23,"fantianwen");
System.out.println(p2.toString());
其中Person类中的age用public修饰,name用private修饰;
Field fieldage=per.getClass().getField("age");
System.out.println("age="+fieldage.get(per));
Field fieldname=Person.class.getDeclaredField("name");
fieldname.setAccessible(true);<span style="font-family: Arial;">//声明private的可获取性</span>
String nn=fieldname.get(per).toString();
System.out.println("name="+nn);
三、数组的反射
Array.getLength:获取数组的长度;Array.get(Object,int)用以获取i位置的数组元素;
public class shiyan {
public static void main(String[] args)
{
int[] a=new int[]{1,2,3};
System.out.println(a);
String[] b=new String[]{"lla","hah","bebe"};
System.out.println(Arrays.asList(b));//String父类就是Object类型。
System.out.println(Arrays.asList(a));//因为是int[],而asList并没有这样的参数类型。只有Object。
printObject(b);
}
public static void printObject(Object object)
{
if(object.getClass().isArray())
{
int len=Array.getLength(object);
for(int i=0;i<len;i++)
{
System.out.println(Array.get(object,i));
}
}
}
}