1.1反射机制
1.1.1反射机制的介绍
什么是反射机制?
Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;或者对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
简单来说就是:在程序运行时,动态的解析类的内部信息。包括注解、属性和方法的功能,我们称之为反射机制。
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)
为什么要用反射机制?
首先我们需要了解一下Java的编译类型:
静态编译:
在编译时确定类型,绑定对象即通过。
实现方式:
1.先引入所需要的的包类的名称
2.通过new实例化
3.取得实例化对象
动态编译:
运行时确定类型,绑定对象。动态编译最大限度地发挥了Java的灵活性,体现了多态的应用,可以减低类之间的耦合性。
实现方式:
1.先实例化对象
2.调用getClass()方法
3.得到完整的包类名称
使用反射的好处是什么?
1.反射可以在运行时加载、探知、使用编译期间完全未知的class。即Java程序可以加载一个运行时才得知名称的class,获取其完整构造,并生成其对象实体、或对其fields设值、或唤起其methods。
2.反射(reflection)允许静态语言在运行时(runtime)检查、修改程序的结构与行为。
在静态语言中,使用一个变量时,必须知道它的类型。在Java中,变量的类型信息在编译时都保存到了class文件中,这样在运行时才能保证准确无误;换句话说,程序在运行时的行为都是固定的。如果想在运行时改变,就需要用到反射。
反射机制提供的功能?
实现Java反射机制的类都位于java.lang.reflect包中:
1.java.lang.Class:代表一个类
2. java.lang.reflect.Method:代表类的方法
3. java.lang.reflect.Field:代表类的成员变量(类的属性)
4. java.lang.reflect.Constructor:代表类的构造器
1.1.2反射的使用
class类的常用方法:
1.获取Class对象的三种方式:
public class Test {
public static void main(String[] args) throws Exception{
//1.获取Class对象
Class c = ToolKit.class;
System.out.println(c);
//2.通过运行时类的对象,调用getClass()方法
ToolKit tk = new ToolKit();
Class c1 = tk.getClass();
System.out.println(c1);
//3.常用方法:调用Class的静态方法
//forName(String className) :根据类名返回类的对象
Class c2 =Class.forName("cn.kgc.kb08.entity.ToolKit");//forName()的括号里面放的是 表示类的全包路径
System.out.println(c2);
//获取全包路径名
String name = c2.getName();
//获取该类的名字
String simpleName = c2.getSimpleName();
//获取全包路径名
String typeName = c2.getTypeName();
System.out.println(name);
System.out.println(simpleName);
System.out.println(typeName);
}
2.获取类的成员变量(属性)的方法:
(1)Field[] fs = c.getDeclaredFields(); //获取当前类中的所有属性对象
getDeclaredField() ;//返回某个属性对象
(2)Field[] fs = c.getFields(); //获取当前类以及父类中的所有公共属性
(3)Field f = …
int modifiledNum = f.getModifies(); //获取属性访问修饰符,返回的是int整数(2是private;0是default;4是protected;1是public)
1.Class c = f.getType();//获取属性的数据类型信息
2.String typeName = c.getName();//获取属性的类型名称
3.String fieldName = f.getName();//获取属性的名称
4.f.setAccessible(boolean visible); //设置属性的可见性
5.f.set(T t,e value); //给t对象的f属性赋值 t:指原始的类型的对象的引用
6.E value = f.get(T t) ;//获取t对象f属性的值
//获取属性的方法属性:
//向获取Class对象
Class c = Class.forName("cn.kgc.kb08.entity.ToolKit");
//返回属性的所有对象: getDeclaredFields();
Field[] fs = c.getDeclaredFields();
for (Field f : fs) {
int modifiersNum = f.getModifiers();//获取属性访问修饰符
System.out.println(modifiersNum);
String name = f.getType().getName();//获取属性类型的名称
System.out.println(name);
String fieldName = f.getName();//获取属性的名称
System.out.println(fieldName);
System.out.println("===========");
}
返回属性的所有对象: getDeclaredFields();
Field[] fs = c.getDeclaredFields();
for (Field f : fs) {
int modifiersNum = f.getModifiers();//获取属性访问修饰符
System.out.println(modifiersNum);
String name = f.getType().getName();//获取属性类型的名称
System.out.println(name);
String fieldName = f.getName();//获取属性的名称
System.out.println(fieldName);
3.获取类的普通方法:
(1) Method[] ms = c.getDeclarMethods();//获取当前类中的所有方法对象
(2)Method[] ms = c.getMethods(); //获取当前类和父类中的所有公共方法
(3)Method m =…
String methodName = m.getName();//获取方法名称
Class c = m.getReturn();//获取方法返回类型
String returnType = c.getName();//获取方法返回类型名称
Class[] parameterType = c.getParameterTypes();//获取方法所有参数类型
m.setAccessible(boolean visible);//设置方法的可见性
E val = (E)m.invoke(T target,Object…parameters);//调用方法 ,
//invoke() :传递object对象及参数调用该对象对应的方法
//普通方法:
Class c = Class.forName("cn.kgc.kb08.entity.ToolKit");
//返回普通方法的单个对象
Method m= c.getDeclaredMethod("setLineCount", int.class);
System.out.println("方法名称:"+m.getName());
System.out.println("访问修饰符:"+m.getModifiers());
System.out.println("返回类型:"+m.getReturnType().getName());
Class<?>[] types = m.getParameterTypes();
int count = 0;
for (Class<?> type : types) {
System.out.println("参数"+(++count)+":"+type.getName());
}
//返回普通方法的所有对象
Class c = Class.forName("cn.kgc.kb08.entity.ToolKit");
Method[] ms = c.getDeclaredMethods();
for (Method m : ms) {
System.out.println("方法名称:" + m.getName());
System.out.println("访问修饰符:" + m.getModifiers());
System.out.println("返回类型:" + m.getReturnType().getName());
Class<?>[] types = m.getParameterTypes(); //方法的参数个数不固定,因而用一个数组来接收
int count = 0;
for (Class<?> type : types) {
System.out.println("参数" + (++count)+":"+ type.getName());
}
4.获取类的构造方法:
//构造方法:
Class c = Class.forName("cn.kgc.kb08.entity.ToolKit");
//通过无参构造创建对象
ToolKit tk = (ToolKit) c.newInstance();//创建类的实例对象
//调用有参构造给ToolKit类的对象赋值
Constructor cons = c.getConstructor(String.class,Integer.class, List.class);
ToolKit tk = (ToolKit) cons.newInstance("arial",100, Arrays.asList("henry","pola","arial"));
System.out.println(tk.getName());
System.out.println(tk.getLineCount());
System.out.println(tk.getList());