java中的反射机制

来源:互联网 发布:上瘾 网络剧 日本评论 编辑:程序博客网 时间:2024/05/19 02:03

一. 先看一下反射的概念:

主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以在运行时装配,不用在组件之间进行源代码的链接。

二. 反射机制的作用:

1.反编译:.class-->.java

2.通过反射机制访问java对象的属性,方法,构造器等内容。

三. 先看一下sun为我们提供的反射机制中的类:

java.lang.Class;                

java.lang.reflect.Constructor; java.lang.reflect.Field;        

java.lang.reflect.Method;

java.lang.reflect.Modifier;


四.具体功能实现:

1. 反射机制获取类的三种方法,

  1. /** 
  2.  * 反射机制获取类有三种方法 
  3.  */  
  4. @Test  
  5. public void testGetClass() throws ClassNotFoundException {  
  6.     Class clazz = null;  
  7.   
  8.     //1 直接通过类名.Class的方式得到  
  9.     clazz = Person.class;  
  10.     System.out.println("通过类名: " + clazz);  
  11.   
  12.     //2 通过对象的getClass()方法获取,这个使用的少(一般是传的是Object,不知道是什么类型的时候才用)  
  13.     Object obj = new Person();  
  14.     clazz = obj.getClass();  
  15.     System.out.println("通过getClass(): " + clazz);  
  16.   
  17.     //3 通过全类名获取,用的比较多,但可能抛出ClassNotFoundException异常  
  18.     clazz = Class.forName("com.java.reflection.Person");  
  19.     System.out.println("通过全类名获取: " + clazz);  
  20. }  
通过类名:class  Reflection.Person

无参构造器

通过getclass():class Reflection.Person

通过全类名获取:class Reflection.Person

2.创建对象:获取类以后来创建类的对象,利用newInstance

/**  * Class类的newInstance()方法,创建类的一个对象。  */  @Test  public void testNewInstance()          throws ClassNotFoundException, IllegalAccessException, InstantiationException {        Class clazz = Class.forName("Reflection.Person");        //使用Class类的newInstance()方法创建类的一个对象      //实际调用的类的那个 无参数的构造器(这就是为什么写的类的时候,要写一个无参数的构造器,就是给反射用的)      //一般的,一个类若声明了带参数的构造器,也要声明一个无参数的构造器      Object obj = clazz.newInstance();      System.out.println(obj);  }  
  无参构造器:  Person{name='null',age=0}

4.ClassLoader类加载器

类加载器详解http://blog.csdn.net/ochangwen/article/details/51473120

/**  * ClassLoader类装载器  */  @Test  public void testClassLoader1() throws ClassNotFoundException, IOException {      //1、获取一个系统的类加载器      ClassLoader classLoader = ClassLoader.getSystemClassLoader();      System.out.println("系统的类加载器-->" + classLoader);        //2、获取系统类加载器的父类加载器(扩展类加载器(extensions classLoader))      classLoader = classLoader.getParent();      System.out.println("扩展类加载器-->" + classLoader);        //3、获取扩展类加载器的父类加载器      //输出为Null,无法被Java程序直接引用      classLoader = classLoader.getParent();      System.out.println("启动类加载器-->" + classLoader);        //        //4、测试当前类由哪个类加载器进行加载 ,结果就是系统的类加载器      classLoader = Class.forName("com.java.reflection.Person").getClassLoader();      System.out.println("当前类由哪个类加载器进行加载-->"+classLoader);        //5、测试JDK提供的Object类由哪个类加载器负责加载的      classLoader = Class.forName("java.lang.Object").getClassLoader();      System.out.println("JDK提供的Object类由哪个类加载器加载-->" + classLoader);  }  

5.Method:对应类中方法

 

public class Person {      private String name;      private int age;        //新增一个私有方法      private void privateMthod(){      }            public Person() {          System.out.println("无参构造器");      }        public Person(String name, int age) {          System.out.println("有参构造器");          this.name = name;          this.age = age;      }        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }        /**      *       * @param age  类型用Integer,不用int      */      public void setName(String name , int age){          System.out.println("name: " + name);          System.out.println("age:"+ age);        }        public int getAge() {          return age;      }        public void setAge(int age) {          this.age = age;      }        @Override      public String toString() {          return "Person{" +                  "name='" + name + '\'' +                  ", age=" + age +                  '}';      }  }  

@Test  public void testMethod() throws ClassNotFoundException, NoSuchMethodException,           IllegalAccessException, InstantiationException, InvocationTargetException {      Class clazz = Class.forName("Reflection.Person");        //1、得到clazz 对应的类中有哪些方法,不能获取private方法      Method[] methods =clazz.getMethods();      System.out.print("        getMethods: ");      for (Method method : methods){          System.out.print(method.getName() + ", ");      }        //2、获取所有的方法(且只获取当着类声明的方法,包括private方法)      Method[] methods2 = clazz.getDeclaredMethods();      System.out.print("\ngetDeclaredMethods: ");      for (Method method : methods2){          System.out.print(method.getName() + ", ");      }        //3、获取指定的方法      Method method = clazz.getDeclaredMethod("setName",String.class);//第一个参数是方法名,后面的是方法里的参数      System.out.println("\nmethod : " + method);        Method method2 = clazz.getDeclaredMethod("setName",String.class ,int.class);//第一个参数是方法名,后面的是方法里的参数      System.out.println("method2: " + method2);        //4、执行方法!      Object obj = clazz.newInstance();      method2.invoke(obj, "changwen", 22);  }  
6.获取方法等的关键字

方法关键字

含义

getDeclaredMethods()

获取所有的方法

getReturnType()

获得方法的放回类型

getParameterTypes()

获得方法的传入参数类型

getDeclaredMethod("方法名",参数类型.class,……)

获得特定的方法

 

 

构造方法关键字

含义

getDeclaredConstructors()

获取所有的构造方法

getDeclaredConstructor(参数类型.class,……)

获取特定的构造方法

 

 

父类和父接口

含义

getSuperclass()

获取某类的父类

getInterfaces()

获取某类实现的接口