JAVA - 类反射

来源:互联网 发布:苍云正太脸型数据 编辑:程序博客网 时间:2024/05/21 17:08

什么是类反射?

来自百度百科的解释:
 
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
 
JAVA反射机制提供了一下功能:
  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法。
 

Class类

正常情况下,需要先有一个类的完整路径引入之后才可以按照固定的格式产生实例化对象,但在JAVA中允许通过一个实例化对象找到一个类的完整信息,那么这就是Class类的功能。在JAVA中所有类的对象实际上都是Class类的实例。

实例化Class类对象的三种方式

package HelloClass;class Hello {}public class GetClassDemo {public static void main(String[] args) throws ClassNotFoundException {Class <?> c1 = null;Class <?> c2 = null;Class <?> c3 = null;//1.c1 = Class.forName("HelloClass.Hello");//2.c2 = new Hello().getClass();//3.c3 = Hello.class;System.out.println("类名称: " + c1.getName());System.out.println("类名称: " + c2.getName());System.out.println("类名称: " + c3.getName());}}


以上方法都可以实例化Class对象,除forName()方法外,其他两种:“对象.getClass()”,"类.class"都需要导入一个明确的类,如果一个类操作不明确时,可能会受到一些限制。但是,forName()只需要以字符串的方式传入即可,具有较大的灵活性。

通过Class调用无参构造实例化对象

package HelloClass;class Person {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String toString() {return "姓名: " + this.name + " 年龄: " + this.age;}}public class GetClassDemo {public static void main(String[] args) throws Exception {Person person = null;Class<?> c = Class.forName("HelloClass.Person");person = (Person) c.newInstance(); //实例化Person对象,替代了原来的new操作 person.setName("jianwei.wang");person.setAge(18);System.out.println(person);}}

以上程序通过Class.forName()方法实例化Class对象之后,直接调用newInstance()方法就可以实例化字符串传入的对象,完全取代了之前使用new关键字的操作,但要记住一点被实例化对象的类中必须存在无参构造方法,如果不存在是无法实例化的。

以下代码演示:在Person类中添加有参构造方法,则实例化的时候会发生错误:

package HelloClass;class Person {private String name;private int age;public Person(String name, int age) {this.setName(name);this.setAge(age);}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String toString() {return "姓名: " + this.name + " 年龄: " + this.age;}}public class GetClassDemo {public static void main(String[] args) throws Exception {Person person = null;Class<?> c = Class.forName("HelloClass.Person");person = (Person) c.newInstance(); //实例化Person对象,替代了原来的new操作 person.setName("jianwei.wang");person.setAge(18);System.out.println(person);}}


 

Exception in thread "main" java.lang.InstantiationException: HelloClass.Personat java.lang.Class.newInstance0(Unknown Source)at java.lang.Class.newInstance(Unknown Source)at HelloClass.GetClassDemo.main(GetClassDemo.java:38)

通过Class调用无参构造实例化对象

需要明确地调用类中的构造方法,并将参数传递进去之后才可以进行实例化操作。具体步骤如下:

  1. 通过Class类中的getConstructors()取得本类中的全部构造方法;
  2. 想构造方法中传递一个对象数据进去,里面包含了构造方法中所需要的各个参数;
  3. 之后通过Constructor实例化对象。
public class GetClassDemo {public static void main(String[] args) throws Exception {Person person = null;Class<?> c = Class.forName("HelloClass.Person");Constructor<?> cons[] = c.getConstructors();person = (Person) cons[0].newInstance("jianwei.wang", 18);System.out.println(person);}}


获取类的结构

可以通过反射得到一个类的完整结构,要适用到java.lang.reflect包中的几个类:

  1. Constructor:表示类中的构造方法;
  2. Field:表示类中的属性;
  3. Method:表示类中的方法。
package HelloClass;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;interface China {public static final String NATIONAL = "China";public static final String AUTHOR = "ABC";public void sayChina();public String sayHello(String name, int age);}class Person implements China {private String name;private int age;public Person() {}public Person(String name, int age) {this.setName(name);this.setAge(age);}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String toString() {return "姓名: " + this.name + " 年龄: " + this.age;}public void sayChina() {System.out.println("作者: " + AUTHOR + ", 国籍 " + NATIONAL);}public String sayHello(String name, int age) {return name + ", 你好! 我今年" + age + "岁了。。。";}}public class GetClassDemo {public static void main(String[] args) throws Exception {Person person = null;Class<?> c = Class.forName("HelloClass.Person");System.out.println("=====取得全部接口=====");Class<?> interfeca[] = c.getInterfaces();for(int i = 0; i < interfeca.length; i++) {System.out.println(interfeca[i].getName());}System.out.println("=====取得父类=======");Class<?> superClass = c.getSuperclass();System.out.println(superClass.getName());System.out.println("=====取得构造方法=====");Constructor<?>[] constructs = c.getConstructors();for(int i = 0; i < constructs.length; i++) {System.out.println(constructs[i]);}System.out.println("=====取得全部方法====="); Method method[]=c.getMethods();         for(int i=0;i<method.length;++i){             Class<?> returnType=method[i].getReturnType();             Class<?> para[]=method[i].getParameterTypes();             int temp=method[i].getModifiers();             System.out.print(Modifier.toString(temp)+" ");             System.out.print(returnType.getName()+"  ");             System.out.print(method[i].getName()+" ");             System.out.print("(");             for(int j=0;j<para.length;++j){                 System.out.print(para[j].getName()+" "+"arg"+j);                 if(j<para.length-1){                     System.out.print(",");                 }             }             Class<?> exce[]=method[i].getExceptionTypes();             if(exce.length>0){                 System.out.print(") throws ");                 for(int k=0;k<exce.length;++k){                     System.out.print(exce[k].getName()+" ");                     if(k<exce.length-1){                         System.out.print(",");                     }                 }             }else{                 System.out.print(")");             }             System.out.println();         }            System.out.println("=====取得本类全部属性=====");    Field[] field = c.getDeclaredFields();  //、。。。。        for (int i = 0; i < field.length; i++) {             // 权限修饰符             int mo = field[i].getModifiers();             String priv = Modifier.toString(mo);             // 属性类型             Class<?> type = field[i].getType();             System.out.println(priv + " " + type.getName() + " "                    + field[i].getName() + ";");         }                System.out.println("=====实现的接口或者父类的属性=====");         // 取得实现的接口或者父类的属性         Field[] filed1 = c.getFields();         for (int j = 0; j < filed1.length; j++) {             // 权限修饰符             int mo = filed1[j].getModifiers();             String priv = Modifier.toString(mo);             // 属性类型             Class<?> type = filed1[j].getType();             System.out.println(priv + " " + type.getName() + " "                    + filed1[j].getName() + ";");         } }}

运行结果:

=====取得全部接口=====HelloClass.China=====取得父类=======java.lang.Object=====取得构造方法=====public HelloClass.Person()public HelloClass.Person(java.lang.String,int)=====取得全部方法=====public void  setAge (int arg0)public int  getAge ()public void  sayChina ()public java.lang.String  sayHello (java.lang.String arg0,int arg1)public java.lang.String  toString ()public java.lang.String  getName ()public void  setName (java.lang.String arg0)public final native java.lang.Class  getClass ()public native int  hashCode ()public boolean  equals (java.lang.Object arg0)public final native void  notify ()public final native void  notifyAll ()public final native void  wait (long arg0) throws java.lang.InterruptedException public final void  wait (long arg0,int arg1) throws java.lang.InterruptedException public final void  wait () throws java.lang.InterruptedException =====取得本类全部属性=====private java.lang.String name;private int age;=====实现的接口或者父类的属性=====public static final java.lang.String NATIONAL;public static final java.lang.String AUTHOR;

通过反射调用类中的方法

使用反射调用类中的方法可以通过Method类完成,操作步骤如下

  1. 通过Class类的getMethod(String name, Class...parameterTypes)方法取得一个Method的对象,并设置次方法操作时所需要的参数类型;
  2. 使用invoke()进行调用,并向方法中传递要设置的参数类型。
public class GetClassDemo {public static void main(String[] args) throws Exception {Person person = null;Class<?> c = Class.forName("HelloClass.Person");Method met = c.getMethod("sayChina"); //调用无参方法met.invoke(c.newInstance());Method met2 = c.getMethod("sayHello", String.class, int.class);String rv = (String) met2.invoke(c.newInstance(), "Jianwei", 18);System.out.println(rv);}}
作者: ABC, 国籍 ChinaJianwei, 你好! 我今年18岁了。。。


BR~

Jianwei Wang


 


0 0
原创粉丝点击