`

day_30Java反射

阅读更多

 

一、java反射机制

 

     1.通过了解java的反射机制,程序员可以更深入的控制程序的运行过程实现。

          1.1通过java反射机制,可以在程序中访问已经装载到jvm中的java对象的描述,

实现访问、检测和修改描述java对象本身信息的功能。

 

       java的反射机制就是增加程序的灵活性,避免将程序写死到代码里,

 

例如:

        实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码,并重新编译。

      使用反射: class.forName("person").newInstance(); 而且这个类描述可以写到配置文件中,如 **.xml, 这样如果想实例化其他类,只要修改配置文件的"类描述"就可以了,不需要重新修改代码并编译。

 

http://www.cnblogs.com/13188196we/p/3144288.html

复制过来的:http://zhidao.baidu.com/question/478254128.html

 

注意:

     在通过方法getFields()和getMethods()依次获得权限为public的成员变量和方法时,

将包含从超类中继承的成员变量和方法;

     而通过方法getDeclardFields()和getDeclaredMethods()只是获得在本类中定义的所有成员变量和方法。

 

 

二、 访问构造方法

 

  a.在通过下列一组方法访问构造方法时,将返回Constructor类型的对象或数组。

每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法。

 

        getConstructors()

        getConstructors(Class<?> ...parameterTypes)

        getDeclaredConstructors()

        getDeclaredConstructors(Class<?> ...parameterTypes)

 

b.如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。

例如:

       ObjectClass.getDeclaredConstructors(String.class,int.class);

       ObjectClass.getDeclaredConstructors(new Class[]{String.class,int.class});

 

Constructor类中提供的常用方法:

 ...

        newInstance(Object...initargs)

 

c.通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采用默认无参构造方法。

 

       setAccessible(boolean flag) 

 

d.如果该构造方法的权限设置为private,默认为不允许通过反射利用newInstance(Object...initargs)

方法创建对象。如果先执行该方法,并将入口参数设为true,则允许创建。

 

e.通过java.lang.reflect.Modifier类可以解析出getModifire()方法的返回值所表示的修饰信息,

在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,

还可以以字符串的形式获得所有修饰符。

 

       isPublic(int mod) 查看是否被public修饰符修饰,如果是则返回true,否则返回false。

toString(int mod) 以字符串的形式返回所有修饰符。

 

 

f.例如:

           判断对象constructors所代表的构造方法是否被private修饰,以及以字符串形式获得该构造方法的所有修饰符。

 

       int modifiers = constructor.getModifiers();

       boolean isEmbelishByPrivate = Modifier.isPrivate(modifiers);

        String embelshment = Modifier.toString(modifiers);

 

三、访问成员变量

 

  3.1、概念

 

      在通过下列一组方法访问成员变量方法时,将返回Field类型的对象或数组。

每个Field对象代表一个成员变量,利用Field对象可以可以操纵相应的成员变量.

 

      getFields()

      getFields(String name)

      getDeclaredFields()

      getDeclaredFields(String name)

 

       如果是访问指定的成员变量,可以通过该成员变量的名称来访问。

例如访问一个名称为birthday的成员变量:

      object.getDeclaredField("birthday");

 

Field提供的常用方法:

       getName() 获得该成员变量的名称

       getType() 获得表示该成员变量类型的Class对象

        get(Object obj,Object value)  将指定对象obj中的该成员变量的值设置为value。

 

四、访问方法

 

         在通过下列一组方法访问方法时,将返回Method类型的对象或数组。

每个Method对象代表一个方法,利用Method对象可以操纵相应的方法。

 

         getMethod()

         getMethod(String name,Class<?>... parameterTypes)

 

         getDeclaredMethod()

          getDeclaredMethod(String name,Class<?>... parameterTypes)

 

        如果是访问指定的方法,需要根据该方法的名称和入口参数的类型来访问。

例如

        访问一个名称为print、入口参数类型依次为String和int型的方法

 

          objectClass.getDeclaredMethod("print",String.class,int.class)

 

           objectClass.getDeclaredMethod("print",new Class[]{String.class,int.class})

 

 

星期一, 十一月 30, 2015 22:38:28

 

学习java反射机制,先大致了解原理,看demo,回过头再看原理。

 

 

1、反射指的是程序借助某种手段检查自己结构的一种能力

 

2、http://zhidao.baidu.com/link?url=Sn2ZROQ_koC-MqwObmubL3qApBYV9lJlPOZuW_ngEI1iGXLW-V8MdO6dpxeTaMGcn9lShAnaCj-7Be4PK6vivK

 

   解析:

          Class.forName(xxx.xx.xx) 返回的是一个类 首先你要明白在java里面任何class都要装载在虚拟机上才能运行。

        这句话就是装载类用的(和new 不一样,要分清楚)。

 

       从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。

       但是使用newInstance()方法的时候,就必须保证:

                      1、这个类已经加载;2、这个类已经连接了。

        而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,            即加载 java API的那个加载器。 

 

         现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。

          这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。

 

      最后用最简单的描述来区分new关键字和newInstance()方法的区别: 

             newInstance: 弱类型。低效率。只能调用无参构造。 

             new: 强类型。相对高效。能调用任何public构造。

 

3、代码案例

    

基本类:
package day30;

public class Person {
	String name;
	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;
	}

	int age ;
	
	public Person() {
		
	}
	
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
}

class SuperMan extends Person implements ActionInterface  {  
    private boolean BlueHair;  
      
	public boolean isBlueHair() {
		return BlueHair;
	}

	public void setBlueHair(boolean blueHair) {
		BlueHair = blueHair;
	}

	public void fly()  
    {  
        System.out.println("超人fly()");  
    }  
      
    public void walk(int m) {  
        // TODO Auto-generated method stub  
        System.out.println("超人walk()" + m);  
    }  
} 

interface ActionInterface{  
    public void walk(int m);  
}  

package day30;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflactTesta {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
		System.out.println("------通过Java反射机制得到类的包名和类名-----");
		Demo1();
		
		System.out.println();
		System.out.println("----验证所有的类都是Class类的实例对象  ----");
		Demo2();
		
		System.out.println();
		System.out.println("----通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在]----");
		Demo3();
		
		System.out.println();
		System.out.println("----通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象 ----");
		Demo4();
	}
	
	public static void Demo1() {
		Person p1 = new Person();
		System.out.println("  获得Demo1包名----"+p1.getClass().getPackage().getName());
		System.out.println("  获得完整的类目----"+p1.getClass().getName());
	}
	
	
	 public static void Demo2() throws ClassNotFoundException  
	    {  
	        //定义两个类型都未知的Class , 设置初值为null, 看看如何给它们赋值成Person类  
	        Class<?> class1 = null;  
	        Class<?> class2 = null;  
	          
	        //写法1, 可能抛出 ClassNotFoundException [多用这个写法]  
	        class1 = Class.forName("day30.Person");  //设置为Person类
	        System.out.println("Demo2:(写法1) 包名: " + class1.getPackage().getName() + ","   
	                + "完整类名: " + class1.getName());  
	          
	        //写法2  
	        class2 = Person.class; //赋值成Person类   
	        System.out.println("Demo2:(写法2) 包名: " + class2.getPackage().getName() + ","   
	                + "完整类名: " + class2.getName());  
	    }  
	
	 //Demo3: 通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在] 
	 /* newInstance()实际上是把new这个方式分解为两步,
	     即首先调用Class加载方法加载某个类,然后实例化。*/
	 public static void Demo3() throws ClassNotFoundException, InstantiationException, IllegalAccessException  
	    {  
	        Class<?> class1 = null;  
	        class1 = Class.forName("day30.Person");  
	        //由于这里不能带参数,所以你要实例化的这个类Person,使用无参构造方法
	        Person person = (Person) class1.newInstance();  
	        person.setAge(24);  
	        person.setName("waxun..");  
	        System.out.println("Demo3: " + person.getName() + "    " + person.getAge());  
	    }  
	
	 //通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象 
	 public static void Demo4() throws ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException  
	    {  
	        Class<?> class1 = null;  
	        Person person1 = null;  
	        Person person2 = null; 
	        Person person3 = null; 
	          
	        class1 = Class.forName("day30.Person");  
	        Constructor<?>[] constructors = class1.getConstructors();  //获取类中所有的构造方法,得到一系列构造函数集合  
	        person1 = (Person) constructors[0].newInstance(); 
	        person1.setName("yuzhou"); 
	        person1.setAge(24);  
	          
	        person2 = (Person) constructors[1].newInstance("xiner",25);  
	        person3 = (Person) constructors[1].newInstance("xiner_b",25);
	          
	        System.out.println("Demo4: " + person1.getName() + " : " + person1.getAge()  
	                + "  ,   " + person2.getName() + " : " + person2.getAge()  
	                ); 
	        System.out.println("Demo4: "+person3.getName() + " : " + person3.getAge()  
	                ); 
	          
	    }  
	 
	 
}
运行结果:
------通过Java反射机制得到类的包名和类名-----
  获得Demo1包名----day30
  获得完整的类目----day30.Person

----验证所有的类都是Class类的实例对象  ----
Demo2:(写法1) 包名: day30,完整类名: day30.Person
Demo2:(写法2) 包名: day30,完整类名: day30.Person

----通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在]----
Demo3: waxun..    24

----通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象 ----
Demo4: yuzhou : 24  ,   xiner : 25
Demo4: xiner_b : 25

 

 

4、代码案例2

package day30;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;



public class ReflactTestb {
	public static void main(String[] args) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException, InstantiationException, ClassNotFoundException {
		System.out.println("---- 通过Java反射机制操作成员变量, set 和 get----");
		Demo5();
		
		System.out.println("----通过Java反射机制得到类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等----");
		Demo6();
	}
	
	 public static void Demo5() throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException, InstantiationException, ClassNotFoundException  
	    {  
	        Class<?> class1 = null;  
	        class1 = Class.forName("day30.Person");  
	        Object obj = class1.newInstance();  
	        /*java.lang.Class<T>
	         *getDeclaredField(String name) 
	         *返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。*/
	        Field personNameField = class1.getDeclaredField("name");  
	        /*java.lang.reflect.AccessibleObject
	         *setAccessible(boolean flag)将此对象的 accessible 标志设置为指示的布尔值。
	         */
	        personNameField.setAccessible(true);  
	        /*set(Object obj, Object value)
	         * 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。*/
	        personNameField.set(obj, "宇宙歆儿");  
	         
	        //get(Object obj)返回指定对象上此 Field 表示的字段的值。
	        System.out.println("Demo5: 修改属性之后得到属性变量的值:" + personNameField.get(obj));  
	          
	    }  
	 
	 public static void Demo6() throws ClassNotFoundException{
		 Class<?> class1 = null;
		 class1 = class1.forName("day30.SuperMan");
		 //取得父类的名字
		 Class<?> class2 = class1.getSuperclass();
		 System.out.println("取得superman的父类名: "+class2.getName());
		 
		 Field[] fields = class1.getDeclaredFields();//获得所表示的类或接口的指定已声明字段
		 for(int i = 0 ; i < fields.length ; i++ ) {
			 System.out.println("类中的成员为: "+fields[i]);
		 }
		//取得类方法
		 Method[] methods = class1.getDeclaredMethods();
		 for(int i = 0;i<methods.length;i++) {
			System.out.println("函数名 : "+methods[i].getName()); 
			System.out.println("函数返回值类型:   "+methods[i].getReturnType());
			System.out.println("函数访问修饰符:" + Modifier.toString(methods[i].getModifiers()));  
	        System.out.println("函数代码写法: " + methods[i]);  
		 }
		 
		//取得类实现的接口,因为接口类也属于Class,所以得到接口中的方法也是一样的方法得到哈  
	        Class<?> interfaces[] = class1.getInterfaces();  
	        for (int i = 0; i < interfaces.length; i++) {  
	            System.out.println("实现的接口类名: " + interfaces[i].getName() );  
	        }  
		 
	 }
	      
	 
}

运行结果:
---- 通过Java反射机制操作成员变量, set 和 get----
Demo5: 修改属性之后得到属性变量的值:宇宙歆儿
----通过Java反射机制得到类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等----
取得superman的父类名: day30.Person
类中的成员为: private boolean day30.SuperMan.BlueHair
函数名 : isBlueHair
函数返回值类型:   boolean
函数访问修饰符:public
函数代码写法: public boolean day30.SuperMan.isBlueHair()
函数名 : setBlueHair
函数返回值类型:   void
函数访问修饰符:public
函数代码写法: public void day30.SuperMan.setBlueHair(boolean)
函数名 : fly
函数返回值类型:   void
函数访问修饰符:public
函数代码写法: public void day30.SuperMan.fly()
函数名 : walk
函数返回值类型:   void
函数访问修饰符:public
函数代码写法: public void day30.SuperMan.walk(int)
实现的接口类名: day30.ActionInterface

 

 

 

5、代码案例3

 

package day30;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflactTestc {
	public static void main(String[] args) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
		System.out.println("---- 通过Java反射机制调用类中方法----");
		Demo7();
		System.out.println();
		System.out.println("----通过Java反射机制获得类加载器----");
		Demo8();
	}
	
	 public static void Demo7() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
		/*java.lang.reflect.Method
		 * Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。
		 * 所反映的方法可能是类方法或实例方法(包括抽象方法)。 */
		 
		 /*java.lang.Class<T>
		  * getMethods() 返回一个包含某些 Method 对象的数组,
		  *这些对象反映此 Class 对象所表示的类或接口
		  *(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。*/
		 Class<?> class1 = null;  
	        class1 = Class.forName("day30.SuperMan");  
	          
	        System.out.println("Demo7: \n调用无参方法fly():");  
	        Method method = class1.getMethod("fly");  
	        method.invoke(class1.newInstance());  
	          
	        System.out.println("调用有参方法walk(int m):");  
	        method = class1.getMethod("walk",int.class);  
	        method.invoke(class1.newInstance(),100); 
	 }
	 
	   /** 
	     * Demo8: 通过Java反射机制得到类加载器信息 
	     *  
	     * 在java中有三种类类加载器。[这段资料网上截取] 
	 
	        1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。 
	 
	        2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类 
	 
	        3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。 
	     *  
	     * @throws ClassNotFoundException  
	     */  
	    public static void Demo8() throws ClassNotFoundException  
	    {  
	        Class<?> class1 = null;  
	        class1 = Class.forName("day30.SuperMan");  
	        String nameString = class1.getClassLoader().getClass().getName();  
	          
	        System.out.println("Demo8: 类加载器类名: " + nameString);  
	    }  	   
}

运行结果:
---- 通过Java反射机制调用类中方法----
Demo7: 
调用无参方法fly():
超人fly()
调用有参方法walk(int m):
超人walk()100

----通过Java反射机制获得类加载器----
Demo8: 类加载器类名: sun.misc.Launcher$AppClassLoader




JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:在运行时判定任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判定任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

 

4
2
分享到:
评论

相关推荐

    java_diary_18.rar_JFC_swing_反射机制_国际化 java

    Day01:java环境与数据类型 Day02:数据运算与数组 Day03:面向对象 Day04:修饰符与类权限 Day05:类与接口 Day06:集合类型 Day07:反射机制与内部类 Day08:异常与Swing图形界面 Day09:swing图形界面与AWT事件...

    day24_枚举_注解_反射.pdf

    反射是Java提供的一种能力,允许程序在运行时检查和操作对象的内部结构。通过反射,我们可以动态地获取类的信息(如类名、方法名、字段名等)并进行操作,如创建对象、调用方法、访问字段等。 例如,使用反射创建一...

    Day43 Java反射(二)

    ### Day43 Java反射(二) #### Java反射机制概述 Java反射机制是Java语言提供的一种在运行时动态访问和操作类、对象、方法和属性的能力。通过反射,开发者可以在程序运行过程中获取类的信息,并能够创建对象、...

    Java_day17上课资料.zip

    在Java_day17的课程中,可能讲解了如何使用Class类、Constructor类、Method类和Field类进行反射操作,这对于实现元编程和插件化系统非常有用。 Java集合框架是存储和管理对象的重要工具。ArrayList、LinkedList、...

    day01-Java入门

    9. **反射机制**:允许在运行时动态检查和操作类及对象。 10. **JavaFX或Swing**:用于构建图形用户界面的库。 通过不断实践和学习,你将逐渐掌握这些知识点,并能够编写出自己的Java程序。记住,编程是一个持续...

    达内Java培训-CoreJava全程笔记(WORD唐亮版)

    CoreJava DAY09 高级语言特征 30 CoreJava DAY10 主方法,静态导入,包装类,枚举 32 CoreJava DAY11 内部类 36 CoreJava DAY12 集合 List 40 CoreJava DAY13 集合 Set 46 CoreJava DAY14 集合 Map 49 CoreJava DAY...

    Java快速入门教程资料_Java快速入门教程资料_JAVA教程资料_most5st_源码

    - `day10资料`:介绍Java反射机制,用于在运行时动态获取类信息并操作对象,以及注解的使用及其自定义。 通过这些资料,学习者可以逐步建立起对Java编程的全面认识,从基础语法到进阶特性,一步步深化理解和实践...

    day_45_bookstore.rar

    本Java视频教程案例是尚硅谷JavaWEB学习完成后的一个总结性案例,由讲师在第45、46、47天带领学员一起完成。 该案例把 JavaWEB 之前学习的大部分技术融合到一起,具体内容涉及:JavaSE、SQL、JDBC、DBUtils、C3P0、...

    毕向东_Java基础视频源代码

    "day24"可能是课程的总结或进阶内容,比如反射、线程同步或者泛型等高级特性。 这些源代码文件是学员跟随视频课程动手实践的宝贵资料,通过实际编写和运行代码,可以加深对Java语言的理解,提高编程能力。每个day的...

    Reflect_day01_all.zip

    在“Reflect_day01_all.zip”压缩包中,包含的资源旨在帮助初学者理解和掌握Java反射的基本用法,同时也为有经验的开发者提供了复习和巩固的机会。以下是关于Java反射机制的详细解释。 1. **什么是反射**: 反射是...

    应用java反射机制打印一个对象.docx

    ### 应用Java反射机制打印一个对象 #### Java反射机制简介 Java反射机制是Java语言的一个强大特性,它允许程序在运行时动态地获取类的信息(如类名、方法名等),并能直接操作这些信息。这使得Java程序能够做到在...

    Java基础_day01

    "Java基础_day01"的学习内容通常涵盖了Java编程的基础概念,是初学者入门的关键步骤。以下是一些重要的Java基础知识,这些内容可能会在学习过程中涉及: 1. **环境配置**:学习Java的第一步是安装JDK(Java ...

    学习笔记 java\CoreJava笔记\CoreJava_day15

    以下是对"CoreJava_day15"学习笔记中可能涉及的一些关键知识点的详细解释: 1. **异常处理**: - 异常是程序运行时出现的错误,Java通过Exception类及其子类来表示这些错误。在Java中,异常处理使用try-catch-...

    Java_day23上课资料.zip

    今天我们将深入探讨“Java_day23上课资料”中的关键知识点,这可能是针对初学者或有一定基础的学习者的一堂进阶课程。 首先,Java的核心特性之一是它的跨平台能力,这得益于Java的“一次编写,到处运行”(Write ...

    达内 CoreJava老师笔记汇总

    CoreJava DAY01 Java概述 1 ...CoreJava DAY16 反射、注释 108 CoreJava DAY17 GUI 120 CoreJava DAY18 awt event 146 CoreJava DAY19-20 多线程 154 CoreJava DAY21-22 IO 174 CoreJava DAY23 网络编程 197

    Java_day15上课资料.zip

    5. **反射机制**:Java反射允许我们在运行时获取类的信息(如类名、方法名)并动态调用方法,为程序提供了强大的灵活性。 6. **设计模式**:在Day15的学习中,可能会涉及一些常见的设计模式,如单例模式、工厂模式...

    Java_day18上课资料.zip

    7. **反射机制**:Java反射允许在运行时检查类、接口、字段和方法的信息,它是动态编程的重要工具。 8. **泛型**:泛型的引入增强了类型安全,使得容器可以存储特定类型的对象,同时避免了强制类型转换。 9. **...

    Java_day20上课资料.zip

    5. **反射机制**:Java反射机制允许程序在运行时动态访问类的信息,如类名、方法名、构造器等,从而实现动态加载类、调用方法等功能。学生会了解Class类的使用,以及如何通过反射进行对象实例化。 6. **设计模式**...

    Java_day07上课资料.zip

    5. **反射**:反射是Java动态类型能力的体现,允许在运行时检查类、接口、字段和方法的信息,甚至动态调用方法和创建对象。这是许多高级功能如插件系统、序列化和动态代理的基础。 6. **设计模式**:设计模式是解决...

    Java基础资料

    Day05可能涉及Java的反射机制,它允许在运行时检查类的信息,并动态调用方法或访问属性。最后,线程的使用也是这一章的重点,包括同步机制(synchronized关键字,wait()和notify()方法)和并发工具类(如Semaphore, ...

Global site tag (gtag.js) - Google Analytics