Java 反射机制总结
关于反射:
part1:备用知识:一般认同的定义是:程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。Perl,Python,Ruby是动态语言,而java和c++、c#是静态语言。但是不同于c++,java有一个非常突出的动态机制,就是反射。
part2:两个术语:
Reflection反射。 我们可以于运行时加载、探知、使用编译期间完全未知的classes。即Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods 定义),并生成其对象实体、或对其fields设值、或唤起其methods。
introspection反省,内省。the ability of the program to examine itself。是一种看透自己的能力。
part3:一般流程:获得类型类->通过类型类获取当前运行的类的相关信息(获得相应方法、字段、或者实例)
1.获得某个类的类型类:
class<?> type=对象.getClass()=类.class=Class.ForName("包.类");
tips:所有类的对象其实都是Class的实例
2.通过类型类获取该类型的相关信息:
类型类.getName() 获得此类运行时的类名
.getSuperclass() 获得此类运行时的父类类型类
.getInterfaces()获得此类运行时的所拥有的接口类型类
3.通过类型类实例化其他类(其他类是指非自己,非类型类)
a.通过无参数的构造函数
Class<?> demo=Class.forName( "Reflect.Person" );Person per=(Person)demo.newInstance();
注意要用无参数的构造函数必须保证有无参数的构造函数。比如:你写了一个有参数的构造函数,默认构造函数就被覆盖了,所以要再自己写一个无参构造函数。
否则报错:
b.通过有参数的构造函数,需要提取他的构造函数
public Object newInstance(String className, Object[] args) throws Exception {Class newoneClass = Class.forName(className);
Class[] argsClass = new Class[args.length];
for (int i = 0, j = args.length; i < j; i++) {
argsClass[i] = args[i].getClass();
}
Constructor cons = newoneClass.getConstructor(argsClass);
return cons.newInstance(args);
}
part3:用途:spring ,struts,hibernate中都有用到,通过配置文件改进Class.ForName("path")中每次都要改动类的所在路径(包名+类名),而改变代码的麻烦。实现不用修改源码来改变代码的功能。
没用反射前(工厂模式):
interface fruit{public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
// 构造工厂类
class Factory{
public static fruit getInstance(String fruitName){
fruit f=null;
if("Apple".equals(fruitName)){
f=new Apple();
}
if("Orange".equals(fruitName)){
f=new Orange();
}
return f;
}
}
class hello{
public static void main(String[] a){
fruit f=Factory.getInstance("Orange");
f.eat();
}
}
用了反射后:
package Reflect;interface fruit{
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
class Factory{
public static fruit getInstance(String ClassName){
fruit f=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();//ClassName在配置文件中取出来
}catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
class hello{
public static void main(String[] a){
fruit f=Factory.getInstance("Reflect.Apple");
if(f!=null){
f.eat();
}
}
}
plus:
1.Class 、Field 、Constructor 等类中的getModifiers() 方法: 以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符.public为3,private、protected都有对应的值 。可以用Modifier.isPublic(Classname.getModifiers())来判断修饰符是否是哪个。
2.invoke方法:通过函数名反射相应的函数
public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {//返回值Object是指meshodName的返回值
Class ownerClass = owner.getClass();
Class[] argsClass = new Class[args.length];
for (int i = 0, j = args.length; i < j; i++) {
argsClass[i] = args[i].getClass();
}
Method method = ownerClass.getMethod(methodName,argsClass); //argsClass是所对应参数类型的类类型
return method.invoke(owner, args); //若owner换成null,则表示取出静态方法。args为参数值
}
以上是 Java 反射机制总结 的全部内容, 来源链接: utcz.com/z/391460.html