Java 反射机制总结

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

回到顶部