`

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事件...

    达内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...

    day_45_bookstore.rar

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

    达内 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

    CoreJava笔记

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

    java Reflection 反射机制 反编译

    package day29; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class ReflectionTest { public static void main(String[] args) { Class c =...

    Java学习day034 反射(一)Class类、捕获异常、利用反射分析类的能力

    day034 反射(一)Class类、捕获异常、利用反射分析类的能力 反射库(reflection library)提供了一个非常丰富且精心设计的工具集,以便编写能够动态操纵Java代码的程序。这项功能被大量地应用于JavaBeans中,它是...

    Reflect_day01_all.zip

    对java反射通过代码Demo来验证反射的原理,怎么使用,对初学者有很大帮助,对曾经学过的人也是一个总结,有利于巩固。包含了java代码实例和笔记。

    java进阶13天资料.zip

    Java进阶13天资料 day01-复习回顾、静态、继承、引用类型使用 day02-抽象类、接口、代码块,final、...day12-JUnit单元测试、反射、注解、动态代理 day13-XML和Dom4j,装饰模式,工厂模式,commons-io工具包,Base64

    day15-类加载器&反射

    day15-类加载器&反射

    day021-反射和注解笔记和代码.rar

    1. 反射: Class 类的实例表示正在运行的 Java 应用程序中的类和接口; 枚举是一种类,注解(指的是注解Annotation)是一种接口; 每个数组都是 Class字节码类中的一个具体 对象 基本的 Java 类型...

    Day 24反射

    Day 24 1. 反射 1.1 Java文件和.class文件的关系 Java文件 Java文件中包含代码的所有内容 .class文件 .java文件通过javac编译工具生成对应的.class字节码文件 包含 Class 完整的包名,类名 Field 成员变量...

    Java基础-day15每日作业卷1

    操作步骤描述(参考讲义1.8)训练案例10训练描述:【讲义--1.9字段(成员变量)与数据操作】一、使用反射机制获取一个类的属性,下列关于getField()方

    day13【JUnit单元测试、反射、注解、动态代理、JDK8新特性.md

    反射、注解

    30天搞定Java–day29(完)

    文章目录每日一考和复习反射反射的应用:动态代理Java 8 的其他新特性Lambda表达式函数式(Functional)接口方法引用与构造器引用方法引用构造器调用强大的Stream APIStream的实例化中间操作终止操作Optional类 ...

    day15-类加载器&反射&模块化1

    声明的所有构造函数的Constructor对象的数组}//Constructor&lt;T&gt; getConstructor(Class&lt;?&gt;... parameter

    整理后java开发全套达内学习笔记(含练习)

    Reflection [java] 反射 [ri'flekʃәn] script n.手写体,小型程序 [skript] serialized vt.序列化,串行化 ['siәriәlaiz]'(serializable adj.)(deserialize反序列化,反串行化) Socket [java] 网络套接字['sɒkit...

    day01.环境变量,HelloWorld,常量

    - **第三部分:JavaSE核心高级应用:**`集合`、`I/O`、`多线程`、`网络编程`、`反射机制`、 - **第四部分:Java新特性:**`Lambda表达式`、`函数式编程`、`新Date/Time API`、`接口的默认、静态和私有方法`、 - **第...

    Java学习路线:day22

    文章目录第10章枚举类与注解枚举类的使用枚举类的理解自定义枚举类使用enum关键字定义枚举类Enum类中的常用方法使用enum关键字定义的枚举类实现...的使用1jdk中4个基本的元注解的使用2利用反射获取注解信息jdk8新特性...

Global site tag (gtag.js) - Google Analytics