1.运行期间,动态获取类想信息以及动态调用对象的方法,来自于Java语言反射机制
反射打破了类的包装机制。反射值Java被视为动态(准动态)语言的关键性质
2.反射机制提供了以下功能
运行时判断任意一个对象所属的类
运行时构造任意一个类的对象
运行时判断任意一个类所具有的成员变量和方法
运行时调用任意一个对象的方法
3.动态语言:“程序运行时,允许改变程序结构或变量类型的语言”
Perl,Python,Ruby是动态语言
C++, Java, C# 是静态语言
Java Script是动态语言,不明确规定变量类型,通过var关键字描述变量类型
var a = 1;-------------a是int
a = "aaaa";--------------a是String
a = false;----------------在运行期间改变了变量类型
4.尽管Java不是动态语言,但是有一个突出的动态相关机制——Reflection
在Java程序运行时,可以加载、使用编译期间完全未知的类;
加载一个运行时才得知名称的类class,得到完整地构造(不包括methods定义),并生成对象的实体、或对fields设值、或唤起methods
这个能力叫做introspection
5.Java Reflection API简介
这些类位于java.lang.reflect包中
1.Class类(特殊位于java.lang包中)
2.Field类:代表类的成员变量(属性)
3.Method类:一个方法对应一个Method对象
4.Constructor类
5.Array类:提供动态创建数组和访问数组元素的静态方法
6.Reflection API 例1——读取命令行参数指定的类名,然后打印这个类所具有的方法信息
要想使用反射,首先要获得想操作类的对应的Class对象
该例子使用Class.forName的静态方法,传入类的全称,获得这个类对应的Class对象
Java中不管一个类有多少对象,这些对象都会对应于,同一个Class对象
Reflection API 例2
要想使用反射,首先要获得想操作类的对应的Class对象该例子使用Java内置的语法: 类名.class 获得一个类对应的Class对象
以下这个方法,创建一个由这个Class对象所表示的类的新的实例
以下这个方法,传入方法的名字的字符串,传入方法的参数所对应的Class对象所构成的数组。因为Java有方法重载,单纯从名字无法区分究竟调用哪个方法
Method类中的invoke方法如下,调用这个方法表示调用Method对象所对应的目标方法,实现对目标方法的调用
传入的第一个参数:方法通过对象来调用,传入这个对象
传入的第二个参数:方法调用传入实际的参数是什么,以数组或可变参数的方式传进来
总结以上程序:
要想通过反射的方式操作某个类
第一步要获得这个类所对应的Class对象,获取Class对象的方式目前有两种:Class.forName(“传类名”)方法和类名.class方法
第二步利用newInstance()方法获得这个类的实例
第三步通过Class对象的getMethod方法获得对应的方法
第四部通过Method对象的invoke方法调用方法
Reflection API 例3
获得一个类所对应的Class对象的第三种方法:Object对象实例.getClass()方法
Class类的getConstructor()方法
Constructor类的newInstance()方法,传入可变参数
以下代码生成了不带参数构造方法的实例
以下方法生成带两个参数构造方法的实例
总结:
要想通过类的不带参数的构造方法生成对象,有两种方式:
a.先获得Class对象,然后通过该对象的newInstance()方法直接生成即可
Class<?> classType = String.class;
Object obj = classType.newInstance();
b.先获得Class对象,通过该对象获得对应的Constructor对象,再通过Constructor对象的newInstance()方法生成
Class<?> classType = Customer.class;
Constructor cons = classType.getConstructor(new class[]{});
Ojbect obj = cons.newInstance(new Object[]{});
要想通过类的带参数的构造方法生成对象,只能使用:
Class<?> classType = Customer.class;
Constructor cons = classType.getConstructor(new class[]{String.class, int.class});
Ojbect obj = cons.newInstance(new Object[]{"hello", 3});
7.Array类提供静态方法
例1
例2 二维数组
Integer.class————返回Integer类所对应的Class对象
Integer.TYPE————返回Integer原生数据类型的类型int(其他包装类也有TYPE属性)
程序在生成对象时使用下面重载的newInstance构造方法,第二个参数传入int类型的数组,表示维度
8.利用反射在类外面调用private方法
第一个类文件:PrivateTest.java
涉及到的方法:
getMethod方法:返回Method对象,这个对象是由调用该方法的对象所表示的类或接口所指定的*public*的成员方法
getDeclaredMethod方法:返回定义过的方法,没强调public
错误程序:
正确程序:
Method类的父类是:java.lang.reflect.AccessibleObject——可访问的对象。这个父类的三个子类分别是:Constructor,Field,Method,用于压制java语言默认的访问控制
AccessibleObject类中的setAccessible方法:如果传入参数为true,则压制访问控制检查。如果为false,则执行java的访问控制检查