黑马程序员 JAVA提高——反射

来源:互联网 发布:壁虎老师java视频教程 编辑:程序博客网 时间:2024/05/17 01:47

----------- android培训java培训java学习型技术博客、期待与您交流! ------------


java中的反射机制

一:什么是反射?

1,反射的概念:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。反射本身并不是一个新概念,尽管计算机科学赋予了反射概念新的含义。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

2,java中的类反射:

反射是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查。
反射是 Java 被视为动态(或准动态)语言的关键,允许程序于执行期 反射API 取得任何已知名称之 class 的內部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可于执行期生成实例、变更 字段內容或唤起 方法


java反射机制:   JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

一句话:java反射就是将类中的各个成分映射称为java类。

了解了反射的基本概念后,我们就要走进java反射,首先介绍反射的基石——Class类


二,Class类——反射的基石

java中万事万物皆为对象,那么在java中各种各样的java类又是不是一个对象呢,答案是肯定的。就是Class类。

具体来说:Class对象就是用来描述,那么描述类的那些属性呢。描述类的成员变量,方法,够着函数,及各种修饰符等等信息。

一句话Class对象就是用来描述java中类的信息的一种特殊的类。

注意:与class的区别,class是java中的关键字,而Class是java中的一个类。不要混淆

下面通过代码和注释简要说明下Class

package cn.itcast.day1;import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.Arrays;public class ReflectTest {public static void main(String[] args) throws Exception {String str1 = "abc";                //获取Class对象的三种方法                Class cls1 = str1.getClass();Class cls2 = String.class;Class cls3 = Class.forName("java.lang.String");                //Class代表类的字节码文件,在内存中只有一份                System.out.println(cls1 == cls2);System.out.println(cls1 == cls3);System.out.println(cls1.isPrimitive());//判断是不是基本类型System.out.println(int.class.isPrimitive());System.out.println(int.class == Integer.class);System.out.println(int.class == Integer.TYPE);System.out.println(int[].class.isPrimitive());System.out.println(int[].class.isArray());//判断是不是数组}}

三:反射的应用

1.java反射--Constructor

首先介绍一下Constructor类,这个类用来封装反射得到的构造器,Class有四个方法来获得Constructor对象

  • public Constructor<?>[] getConstructors()      返回类中所有的public构造器集合,默认构造器的下标为0
  • public Constructor<T> getConstructor(Class<?>... parameterTypes)   返回指定public构造器,参数为构造器参数类型集合
  • public Constructor<?>[] getDeclaredConstructors()  返回类中所有的构造器,包括私有
  • public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回任意指定的构造器

package cn.itcast.day1;import java.lang.reflect.Constructor;class Person{private String name;private int  age;public Person(){System.out.println("共有的空的构造函数");}private Person(String name){this.name = name ;System.out.println("私有的构造器");}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;}@Overridepublic String toString() {return this.name+"....."+this.age;}}public class Test {public static void main(String[] args) throws Exception {method();}private static void method() throws Exception{Person p = new Person();Class cls1 = p.getClass();//获取构造方法Constructor//      getConstructor()  only for public //      getDeclaredConstructor()  global access all                 //指定参数列表获取特定的方法        Constructor con = cls1.getDeclaredConstructor(String.class);        con.setAccessible(true); //设置可访问的权限,暴力反射,强行的使用私有的构造器        Object obj = con.newInstance("zhangsan");        System.out.println(obj);  //打印一下这个对象的信息        //获取所有的构造方法集合,返回构造器的数组        Constructor con1[] = cls1.getDeclaredConstructors();        System.out.println(con1.length);}}

注意:

a:   获取构造方法Constructor中 getConstructor()和 getDeclaredConstructor()  的区别:
前者只是获取共有的构造器,而后者可以获取私有的构造器,当然需要:  con.setAccessible(true); //设置可访问的权限
b:newInstance()用来调用空的构造函数来实例化变量。否则的话就要传入相应的参数。


2,java反射——Field

 了解了构造器,其实你可以猜到成员变量的获取方法了,成员变量用Field类进行封装。

       主要的方法非常的类似:
  • public Field getDeclaredField(String name)  获取任意指定名字的成员
  • public Field[] getDeclaredFields()             获取所有的成员变量
  • public Field getField(String name)           获取任意public成员变量
  • public Field[] getFields()                          获取所有的public成员变量
代码说明:
private static void method_1() throws Exception {/**         * 获取成员变量Field         * getField()         * getDeclaredField()         * */Person p = new Person();Class cls1 = p.getClass();        Field field = cls1.getDeclaredField("name");        field.setAccessible(true);              System.out.println((String)field.get(p));        Field[] fields = cls1.getDeclaredFields();        for (Field f : fields){        System.out.println(f.getName());        }}

分析:对比Constructor的学习,同理的
有一点注意:你要调用对象的字段,所以你要传入你要调用那个对象,这是很显然的。


2,java反射——Method

轻车熟路:同理先看Methodde 构造器:

  • public Method[] getMethods()    获取所有的共有方法的集合
  • public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 参数1:方法名 参数2:参数类型集合  
  • public Method[] getDeclaredMethods()  获取所有的方法
  • public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法
代码案例:

private static void method_2() throws Exception {/**         * 调用类的方法 Method         * getMethod()         * getDeclaredMethod()         *          * */Person p = new Person();Class cls1 = p.getClass();        Method f = cls1.getMethod("getName", null);        Object name = f.invoke(p, null);        System.out.println((String)name);        Method[] methods = cls1.getDeclaredMethods();                for(Method method : methods){        System.out.println(method.getName());        }        }

总结:要想调用一个method实例,很容易的想到,要传给一个对象,即要调用那个对象的方法,自然还要传入,形参。

问题?若果一个方法伪静态的,不需要对象则传入null;



PS:反射的其他细节会在以后的博文中介绍



---- ASP.Net+Android+IOS开发.Net培训、期待与您交流!--------详细请查看:http://edu.csdn.net------