1、该如何获取一个类的字节码文件的对象呢?(获取字节码文件的三种方式)。
1)、要想对字节码文件的解剖,必须要要有字节码文件的对象
2)、如何获取字节码文件的对象
2、获取Class中的构造函数。
1)、空参的构造方法。
2)、带参数的构造方法。
3、一般被反射的类都带有空参,方便使用。
4、反射机制获取字节码文件中的字段。
例子一、
public class ReflactDemo1 {
/*
* 获取字节码文件的方式有三种:
* 1、Object类中的getClass()的方法,想要用这种方式,必须要明确具体的类,并创建对象。麻烦。
*/
public static void f_1(){
Person p=new Person();
Class clazz=p.getClass();
Person p1=new Person();
Class clazz1=p1.getClass();
System.out.println(clazz==clazz1);
}
/*
* 方式二
* 2、任何类型数据都具备一个静态的属性,class来获取对应的class对象。相对简单,但是还是要明确
* 用到类中的静态成员。
* 还是不够扩展。
*/
public static void f_2(){
Class clazz=Person.class;
Class claszz1=Person.class;
System.out.println(claszz1==clazz);
}
/*
* 方式三:-----要求重点掌握,推荐在今后的反射中就用这种方式。
* 只要通过给定的类的字符串名称就可以获取该类的字节码文件的对象,更为扩展。
* 可是用Class类中的方法完成。
* 该方法就是forName()。
*
* 这种方式只要有名称就行,更为方便,扩展性更强。
*/
public static void f_3() throws Exception{
String clazzName="com.fjx.bean.Person";//这里的类名要写完整的类名,类同包名一起写上。
Class clazz=Class.forName(clazzName);
System.out.println(clazz);
}
public static void main(String[] args) throws Exception {
//f_1();
//f_2();
f_3();
}
}
例子二、
public class ReflactDemo2 {
public static void main(String[] args) throws Exception {
//createNewObject();
createNewObject_2();
}
public static void createNewObject_2() throws Exception{
//com.fjx.bean.Person p=new com.fjx.bean.Person("da",32);
/*
* 当获取指定名称对应类中所体现的对象时。
* 而该对象初始化不使用空参数的构造方法该怎么办呢?
* 既然是通过指定的构造函数,进行对象的初始化,
* 所以应该先获取到该构造函数,通过字节码文件对象即可完成。
* 该方法是:getConstructtor(paramType);
*/
String clazzName="com.fjx.bean.Person";
//寻找该名称的类文件,并加载进内存,产生Class(字节码文文件)对象。
Class clazz=Class.forName(clazzName);
//获取到了指定的构造函数的对象,
Constructor con=clazz.getConstructor(String.class,int.class);
//根据指定的构造的函数newInstace()方法进行对象的初始化。
con.newInstance("小面",12);
}
public static void createNewObject() throws Exception{
/*
* 早期,new的時候,根据类被new的类的名称找寻该类的字节码的文件,并加载进内存,
* 并穿件该字节码文件的对象并接着创建该字节码文件的对应的Person对象。
*/
//com.fjx.Person p=new com.fjx.Person();
//現在
String clazzName="com.fjx.bean.Person";
Class clazz=Class.forName(clazzName);//找寻该名称的类,并加载进内存,并产生Class对象
//如何产生该类的对象呢?-----连字节码文件都可以取到了,new对象简直就是易如反掌。
/*
* newInstance方法
* 创建此 Class 对象所表示的类的一个新实例。如同用一个带有一个空参数列表的 new 表达式实例化该类。
* 如果该类尚未初始化,则初始化这个类。
*/
Object obj=clazz.newInstance();//这就是new一个对象执行的方法。
}
}
例子三、
public class ReflactDemo3 {
/*
* 获取字节码文件中的字段
*/
public static void main(String[] args) throws Exception {
getFeid();
}
public static void getFeid() throws Exception{
String clazzName="com.fjx.bean.Person";
Class clazz=Class.forName(clazzName);//获取字节码文件的对象。
/*
* 获取字段的对象
*/
//凡是写getxxx()获取到字段的都是公共的修饰符的字段。
Field field=null;//clazz.getField("age");//age是私有的,获取失败。
field=clazz.getDeclaredField("name");
//对私有的字段的访问取消权限检查,暴力访问
field.setAccessible(true);
System.out.println(field);
/*
* 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
* 包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。返回数组中的元素没有排序,
* 也没有任何特定的顺序。如果该类或接口不声明任何字段,或者此 Class 对象表示一个基本类型、
* 一个数组类或 void,则此方法返回一个长度为 0 的数组。
*/
//凡是写getDeclrearedxxx()获取到的字段,(私有的,共有的,保护的,默认的)都可以获取
/*
* 操作字段
* 1、字段的设置值
* 2、字段的获取值
*/
Object obj=clazz.newInstance();//new获取类的空参的对象
field.set(obj, "你好!");
Object o=field.get(obj);//哪个类的字段。
System.out.println(o);
}
}
例子四、
public class ReflactDemo4 {
///反射机制中的方法(函数)的获取
public static void main(String[] args) throws Exception {
//getMethodDemo();
//getMethodDemo2();
getMethodDemo3();
}
/*
* 获取指定的Class中的公共函数。
*/
public static void getMethodDemo() throws Exception{
Class clazz=Class.forName("com.fjx.bean.Person");
Method[] methods=clazz.getMethods();//获取字节码中方法的数组,获取的都是共有的方法
methods=clazz.getDeclaredMethods();//只获取本类中的方法,包含私有
for(Method method:methods){
System.out.println(method);
}
}
/*
* 反射中的无参的一般方法的的获取。
*/
public static void getMethodDemo2() throws Exception{
//运行一个方法需要对象,如果不是空参,还需要参数。
Class clazz=Class.forName("com.fjx.bean.Person");
Method method=clazz.getMethod("show", null);//获取空参的一般的方法
Constructor con=clazz.getConstructor(String.class,int.class);
Object obj=con.newInstance("小明",20);
method.invoke(obj, null);
}
/*
* 反射中的无参的一般方法的的获取。
*/
public static void getMethodDemo3() throws Exception{
//运行一个方法需要对象,如果不是空参,还需要参数。
Class clazz=Class.forName("com.fjx.bean.Person");
Method method=clazz.getMethod("paramMethod",String.class,int.class);//获取空参的一般的方法
Constructor con=clazz.getConstructor(String.class,int.class);
Object obj=clazz.newInstance();
method.invoke(obj, "小明",20);
}
}
图片
图片一、
图片二、