java反射原理,应用
2019-08-29 09:02:12来源:博客园 阅读 ()
java反射原理,应用
java类的加载过程
调用java命令运行程序时,该命令会启动一条java虚拟机进程,该程序的所有线程都会运行在这个虚拟机进程里面。程序运行产生的线程、变量都处于这个进程,共同使用该JVM进程的内存区。
类加载过程
当程序调用一个类的时候,该类的class文件会被读入到内存中,用一个数组存放,产生一个对应的类对象。此时class还不可使用。而后开始检查该class文件是否正确,然后给类中的静态变量分配储存空间。最后对静态对象和静态代码块执行初始化工作。
如果该类存在父类。而且没有被加载,那么就会先加载初始化父类。并且先执行类中的初始化语句。
反射
反射就是在class文件被加载到JVM的时候进行操作的。因为java类被编译为class文件。所以使用反射获取class文件从而拿到java类的所有信息。
即:java类中的所有元素,包括属性,方法,都会被看做一个对象。
如何获取class的对象
java是面向对象语言,万事万物皆为对象。即所有类也是一个对象。是lang包下的Class类的对象:java.lang.Class的对象。
有三种获得方式:
1、通过对象类的对象获取
//首先创建类的对象 Stu stu = new Stu();
在不知道类名的情况下,传入一个对象,可以使用getClass()方法获得类名
//class获取该类 Class getclass = stu.getClass();
2、通过类名获取
//跳过对象类创建对象的过程 Class getclass = Stu.class;
3、通过类名获取,但是会有异常抛出,并且需要强转类型
最常用
try{
Class getclass = (Class) Class.forName("Stu");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
通过类的对象获取属性,方法
此时需要调用Method类:(以下为Api内容)
Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
Method 允许在匹配要调用的实参与底层方法的形参时进行扩展转换;但如果要进行收缩转换,则会抛出 IllegalArgumentException。
首先:获得该类的所有成员方法,接上文的Class对象getClass
getMethods() :方法是获得类所有的public方法。
Method[ ] methods = getclass.getMethods();
getDeclareMethods() : 方法是获得类所有方法,不考虑权限。但是不包括父类继承的方法。
Method[ ] methods = getclass.getDeclareMethods();
开发尽量少用继承
遍历集合:getReturnType() : 得到方法的返回值类型
getName() : 得到方法名
先获取类型,再获取方法名
Class returnType = methods[ i ].getReturnType();
String returnTypeName = returnType.getName();
现在拿到了方法的返回值类型,方法名,还需要方法的参数列表,因为一个方法的参数列表可能有多个,所以需要先得到参数列表的集合,遍历得到单个参数类型
public Class<?>[ ] getParameterTypes()
按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。如果底层方法不带参数,则返回长度为 0 的数组。
返回:此对象所表示的方法的参数类型 (来自Api)
Class[ ] paramTypes = methods[ i ].getParameterTypes();
由:paramTypes[ i ].getName(); 得到参数类型名。
参数名由Java8提供的Parameter类可以得到参数名。
Parameter[ ] parameters = method[ i ].getParameters();
遍历该集合可以得到参数名----一般编译器默认不编译参数名的,所以可能获得的是arg0;
//参数类型 String Type = parameters[ i ].getType().toString();
//参数名 String name = parameters[ i ].getName();
获取成员变量
方法是Method类的对象,成员变量是Field类的对象。
getFields() : 获得所有公有成员变量
getDeclaredFields() : 获得所有自己声明的成员变量,不考虑权限,,但是不包括父类继承的。
Fields[ ] fields = getclass.getFields();
getType() : 获得成员变量的类型
getName() : 获得成员变量名
String name = fields[ i ].getType().getName();
获取构造函数
构造函数是Constructor类的对象;
//获得构造函数集合 区别同上
Constructor[] constructors1 = class1.getConstructors();
Constructor[] constructors2 = class1.getDeclaredConstructors();
遍历得到类型:
for (Constructor constructor : constructors2) {
Class[] paramTypes = constructor.getParameterTypes();
for (Class paramType : paramTypes) {
String paramTypeName = paramType.getName();
}
}
通过反射调用方法
获取类类型,然后获取方法类型
try{
Class getclass = (Class) Class.forName("Stu");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//第一个参数表示方法名,后面依次为方法的参数类型,没有则不传
Method[ ] methods = getclass.getMethod(" FunctionName ", FunctionType)
methods.function(类对象,方法参数)
eg:
类方法
public class Stu {
public void add (int a,int b){ return a+b;}
}
获取类对象,获取方法,调用方法
Stu stu = new Stu();
try{
Class getclass = (Class) Class.forName("Stu");
Method func = getclass.getMethod("add",int.class,int.claaa);
func.add(stu,2,3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
1 public class User { 2 private int id; 3 private String name; 4 public String addr; 5 6 private void speak(int a,int b){ 7 System.out.println("私有方法"); 8 } 9 public void eat(String a){ 10 System.out.println("公有方法"); 11 } 12 public int run(Boolean a){ 13 System.out.println("共有有返回值方法"); 14 return 4; 15 } 16 17 public User(int id, String name, String addr) { 18 this.id = id; 19 this.name = name; 20 this.addr = addr; 21 } 22 }JavaBean
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test { public static void main(String[] args) throws ClassNotFoundException { //拿到对象 Class clazz = Class.forName("User"); //通过对象拿类的方法,属性 //拿到所有共有方法 Method[] getMethon1 = clazz.getMethods(); for (Method method : getMethon1) { System.out.println("打印共有方法名:"+method.getName()); System.out.println("打印共有方法返回值类型:"+method.getReturnType()); Class[] funcType = method.getParameterTypes(); for (Class aClass : funcType) { System.out.println("打印该方法的参数类型列表: "+aClass.getTypeName()); } } System.out.println("-----------------------------------"); //获得该类自己创建的方法 Method[] getMethon2 = clazz.getDeclaredMethods(); for (Method method : getMethon2) { System.out.println("打印所有创建方法名:"+method.getName()); System.out.println("打印所有创建方法返回值类型:"+method.getReturnType()); Class[] funcType2 = method.getParameterTypes(); for (Class aClass : funcType2) { System.out.println("打印该方法的参数类型列表: "+aClass.getTypeName()); } } //拿到公有成员变量 Field[] fields = clazz.getFields(); for (Field field : fields) { System.out.println("打印该变量的变量名:"+field.getName()); System.out.println("打印该变量的类型:"+field.getType()); } //拿到该类创建的成员变量 Field[] fields1 = clazz.getDeclaredFields(); for (Field field : fields1) { System.out.println("打印该变量的变量名:"+field.getName()); System.out.println("打印该变量的类型:"+field.getType()); } //拿到构造函数 Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println("打印构造方法的名 : "+constructor.getName()); //拿到构造方法的参数列表 Class[] funcTypeCons = constructor.getParameterTypes(); for (Class funcTypeCon : funcTypeCons) { System.out.println("打印参数类型:"+funcTypeCon.getTypeName()); } } } }
打印共有方法名:run 打印共有方法返回值类型:int 打印该方法的参数类型列表: java.lang.Boolean 打印共有方法名:eat 打印共有方法返回值类型:void 打印该方法的参数类型列表: java.lang.String 打印共有方法名:wait 打印共有方法返回值类型:void 打印共有方法名:wait 打印共有方法返回值类型:void 打印该方法的参数类型列表: long 打印该方法的参数类型列表: int 打印共有方法名:wait 打印共有方法返回值类型:void 打印该方法的参数类型列表: long 打印共有方法名:equals 打印共有方法返回值类型:boolean 打印该方法的参数类型列表: java.lang.Object 打印共有方法名:toString 打印共有方法返回值类型:class java.lang.String 打印共有方法名:hashCode 打印共有方法返回值类型:int 打印共有方法名:getClass 打印共有方法返回值类型:class java.lang.Class 打印共有方法名:notify 打印共有方法返回值类型:void 打印共有方法名:notifyAll 打印共有方法返回值类型:void ----------------------------------- 打印所有创建方法名:run 打印所有创建方法返回值类型:int 打印该方法的参数类型列表: java.lang.Boolean 打印所有创建方法名:speak 打印所有创建方法返回值类型:void 打印该方法的参数类型列表: int 打印该方法的参数类型列表: int 打印所有创建方法名:eat 打印所有创建方法返回值类型:void 打印该方法的参数类型列表: java.lang.String 打印该变量的变量名:addr 打印该变量的类型:class java.lang.String 打印该变量的变量名:id 打印该变量的类型:int 打印该变量的变量名:name 打印该变量的类型:class java.lang.String 打印该变量的变量名:addr 打印该变量的类型:class java.lang.String 打印构造方法的名 : User 打印参数类型:int 打印参数类型:java.lang.String 打印参数类型:java.lang.String测试结果
原文链接:https://www.cnblogs.com/Ruoqian/p/rq207_01.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- Java--反射(框架设计的灵魂)案例 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash