/*
java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法。
对于任意一个对象,都能够调用它的任意一个方法和属性。
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
动态获取类中的信息,就是java反射。
可以理解为对类的解剖。
要想对字节码文件进行解剖,必须要有字节码文件对象。
那么如何获取字节码文件对象呢?
获取字节码对象的方式:
1.Object类中的getClass方法。
想要用这种方式,必须要明确具体的类,并创建对象。
麻烦。
2.任何数据类型都具备一个静态的属性.class来获取其对应的class对象。
相对简单,还是需要明确用到类中的静态成员。
还是不够扩展。
3.只要通过给定类的字符串名称就可以获取该类,更为扩展。
可以用Class类中的方法完成。
该方法就是forName();
这种方式只要有名称即可,更为方便,扩展性更强。
*/
//获取Class中的字节码对象
import java.lang.*;
class Person{
private int age;
private String name;
public Person(){
System.out.println("Person run");
}
public Person(String name,int age){
super();
this.age = age;
this.name = name;
System.out.println("Person param run"+this.name+":"+this.age);
}
public void show(){
System.out.println(name+"...show run..."+age);
}
private void method(){
System.out.println(" method run ......");
}
public void paramMethod(String str,int num){
System.out.println("paramMethod run..."+str+":"+num);
}
public static void staticMethod(){
System.out.println(" staticMethod run......")
}
}
//获取Class对象的三种方式
import java.lang.*;
class ReflectDemo{
public static void main(String[] args) throws ClassNotFoundException{
getClass_1();
getClass_2();
getClass_3();
}
/*
方式一:
*/
public static void getClass_1(){
Person p = new Person();
Class clazz = p.getClass();
}
/*
方式二:
*/
public static void getClass_2(){
Class clazz = Person.class;
}
/*
方式三:
*/
public static void getClass_3()throws ClassNotFoundException{
String className = "cn.study.bean.Person";
Class clazz = Class.forName(className);
System.out.println(clazz);
}
}
/*-------------------------------------------------------------------*/
//获取Class中的构造函数
import java.lang.*;
class ReflectDemo{
public static void main(String[] args)throws ClassNotFoundException{
//获取无参构造函数
createNewObject_1();
//获取有参构造函数
createNewObject_2();
}
public static void createNewObject_1()
throws ClassNotFoundException,IllegalAccessException,Exception{
//早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
//并创建该字节码文件对象,并接着创建该直接文件的对应的Person对象。
//cn.study.bean.Person p = new cn.study.bean.Person();
//现在:
String name = "cn.study.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Class clazz = Class.forName(name);
//如何产生该类的对象呢?
Object obj = clazz.newInstance();
}
public static void createNewObject_2()
throws ClassNotFoundException,IllegalAccessException,Exception{
//cn.study.bean.Person p = new cn.study.bean.Person("小强",19);
/*
当获取指定名称对应类中的所体现的对象时,
而该对象初始化不适用空参数构造函数时该怎么办呢?
既然是通过指定的构造函数进行对象的初始化,应该先获取到该构造函数。
通过字节码文件对象即可完成,该方法是getConstructors();--公有
getConstructors(paramterTypes);
*/
String name = "cn.study.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Class clazz = Class.forName(name);
//获取到了指定的构造函数对象。
Constructor constructor = clazz.getConstructor(String.class,int.class);
//通过该构造器对象的newInstance方法进行对象的初始化。
Object obj = constructor.newInstance("小强",19);
}
}
/*-----------------------------------------------------------*/
//获取字段
class ReflectDemo{
public static void main(String[] args)throws ClassNotFoundException{
//获取字节码文件中的字段。
getFieldDemo();
}
/*
获取字节码文件中的字段。
*/
public static void getFieldDemo() throws Exception{
Class clazz = Class.forName("cn.study.bean.Person");
Field field = clazz.getDeclaredField("age");//可以获取全部字段,包含私有
//对私有字段的访问取消权限检查。
field.setAccessible(true);//暴力访问方式
Object obj = clazz.newInstance();
field.get(obj);
System.out.println(obj);
}
}
/*-----------------------------------------------------------*/
//获取字段
class ReflectDemo{
public static void main(String[] args)throws Exception{
//获取指定Class中的函数。
getMethodDemo();
//获取无参数方法并运行
getMethodDemo_1();
//获取有参数方法并运行
getMethodDemo_2();
}
/*
获取指定Class中的函数。
*/
public static void getMethodDemo()throws Exception{
Class clazz = Class.forName("cn.study.bean.Person");
//获取的都是共有的方法
Method[] methods = clazz.getMethods();
for(Method method : methods){
System.out.println(method);
}
//获取私有方法
Method[] pmethods = clazz.getDeclaredMethods();
for(Method method : pmethods){
System.out.println(method);
}
}
//获取无参数方法并运行
public static void getMethodDemo_1()throws Exception{
Class clazz = Class.forName("cn.study.bean.Person");
//获取空参数一般方法
Method method = clazz.getMethod("show",null);
//运行获取到的方法
//Object obj = clazz.newInstance();
Constructor constructor = clazz.getConstructor(String.class,int.class);
Object obj = constructor.newInstance("小明",20);
method.invoke(obj,null);
}
//获取有参数方法并运行
public static void getMethodDemo_1()throws Exception{
Class clazz = Class.forName("cn.study.bean.Person");
Method method = clazz.getMethod("paramMethod",String.class,int.class);
Object obj = class.newInstance();
method.invoke(obj,"小强",89);
}
}
java反射
最新推荐文章于 2023-07-20 15:13:23 发布