Java反射机制
来源:互联网 发布:java 日期相差天数 编辑:程序博客网 时间:2024/06/10 13:51
反射,又是个听起来挺高大上的东西啊~
我们知道在Java中有句至理名言,万事万物皆对象,当 A a = new A();的时候,有没有想过这个A是什么类型的?我在这里理解为它是Class类型,那要如何拿到Class对象呢,介绍三种方法:
1...Class c = A.class;//这个能拿到class对象说明在Class中是有个静态成员的class
2...Class c = new A().getClass();
3...Class c = Class.forName("com.xxx.A");//参数要完整的包名路径
通过上面方法就能拿到Class对象了,那比如A类里面有个方法,我要如何调用?这当然要拿到A对象实例了,如何拿?
A a = (A)c.newInstance();//newInstance()返回的Object对象,需要转成A才能调用A的方法,而且要求A类中有无参构造器,这个会调用无参构造方法,还要捕获异常。
类加载分为静态加载和动态加载,我们常用的new方式就属于静态加载,这种加载的弊端就是如果我们要加载的类是不存在的,那编译无法通过。但是有个问题,我们程序执行中并不一定必须要new出这个不存在的对象,比如说程序中我们控制在某条件下new:
int num = 1;
if(num == 0){ A a = new A();} else if(num == 1){B b = new B();}//没有A类有B类
这个例子可能比较极端,反正大概就这么个意思,有时候A对象可能并不是每次都需要的,但这时是无法通过编译,更不能执行了
所以动态加载就可以解决这种问题。首先可以定义一个接口IFace,让我们的类B继承这个接口,再用Class.forName();能拿到Class对象,如果参数传"com.xxx.A",A不存在的话这里运行时会抛异常,但并不会导致无法编译,而且此时是不影响我们对B对象的使用,想使用B的方法那就可以c=Class.forName("com.xxx.B")拿到B的class对象再IFace instance = (IFace)c.newInstance();来调用;当要有个D类的时候就可以让D去实现IFace接口,已同样的方式调用D的方法了。简单打下代码
Interface IFace{ void eat();}
class B implements IFace{ void eat("B eat");}
class MyStart{ main...(){try{ Class c = Class.forName("com.xxx.B");IFace iface = (IFace)c.newInstance();iface.eat();}catch(...){...} }}
反射有一些常用的方法,比如获取类的信息:
Method[] methods = c.getMethods();//获取所有public函数,包括从父类继承而来的方法
Method[] dMethods = c.getDeclaredMethods();//获取该类自己的方法
method.getReturnType().getName();//获取某方法返回值类型的类型
method.getName();//获取方法名
method.getParameterTypes();//参数的class数组 ,调用其getName就能获取参数类型了
Method method = c.getMethod("append",new Class[]{String.class,String.class});
Object obj = method.invoke(c,new Object[]{"abc","def"});//调用两个String参数的方法并传入参数
Object obj = method.invoke(c,"abc","def");//和上面一样,因为参数是可变参数嘛,这么写也可以
成员变量:
Field[] fields = c.getFields();//获取所有public成员变量
Field[] dFields = c.getDeclaredFields();//获取该类自己声明的成员变量,包括私有
Field field = c.getDeclaredField("xxx");//获取某个成员变量
field.set(c,"");//可给其赋值,但私有的需要设置accessible,否则抛出异常
fieldAge.setAccessible(true);// 打破封装,可访问私有
field.getType().getName();//获取成员变量类型
field.getName();//成员变量名称
Modifier.toString(field.getModifiers());//获取修饰符
构造方法:
Constructor[] constructors = c2.getConstructors();//获取所有public的构造方法
Constructor[] constructors = c2.getDeclaredConstructors();//获取所有自定义的构造方法
Constructor constructor = c2.getDeclaredConstructor(String.class);//获取对应参数的构造方法,参数为可变参数
constructor.getParameterTypes();//构造函数参数类型列表,getName获取参数类型
反射还有一个不知道有什么作用的作用,比如一个存放int类型的集合,它的泛型是int,我们可以用反射给这个集合中加入其它类型的数据,比如String类型,因为泛型只是一种类似于编译时的检查机制,在运行时是不存在泛型这个概念的,所以可以用反射跳过编译错误成功加到集合中,而且对于两个不同泛型的集合,他们的class是相同的~
- 【反射】JAVA反射机制
- 【Java】JAVA反射机制
- Java 反射机制[Field反射]
- Java 反射机制[Method反射]
- Java反射机制笔记-反射机制
- java的反射机制
- Java的反射机制
- java反射机制详解!
- Java反射机制
- Java的反射机制
- java 反射机制--侯捷
- java反射机制
- java反射机制
- [候捷]Java反射机制
- java 反射机制
- java 反射机制初探
- 关于Java反射机制
- java反射机制
- VC中查看键盘的虚拟键值
- 【HDU 1599 find the mincost route】
- 链表操作之翻转链表以及求倒数第K个节点
- swift蛋疼的初始化过程
- JMS入门(二)--JMS简单例子
- Java反射机制
- docker学习4--容器
- Tomcat配置JNDI数据源
- 选择排序
- 键树
- C# 多肽
- Android开发中的小技巧
- Find the Duplicate Number--重复数字问题
- 哈佛结构/冯诺依曼结构详细分析