您的位置:首页 > 编程语言 > Java开发

Java反射的简单使用

2015-12-25 17:09 405 查看
内容整理自慕课网的反射课程

反射的核心,就在于Java中万物皆对象的思想。

反射可以动态记载类,调用方法,使用属性,类似于C++的DLL动态加载,但是比C++要更方便,更灵活,可以直接通过类名字符串来获取类,而如果是C++,导出类的话,需要相应的头文件来描述类信息,Java反射不需要。DLL可以动态加载,但是DLL是在编译前加载,而反射可以在运行时加载。DLL的优势是可以用不同语言去实现DLL库,而反射只能是Java的jar包。

反射是编译后的结果,可以用反射来绕开模板编程的类型检测,因为带类型的模板,对类型的检测是编译期的,类型不匹配无法通过编译,而编译后的模板对任何类型都是一样的,可以通过反射来证明(方法:通过反射获得两个不同类型模板的对象的类类型进行比较,结果为true)

以下内容没有提及数组反射(课程里没有)

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

/*
* 类(本身)是java.lang.class的对象
* Class.forName("类的全称")
*/
public class ClassUtil {
//获取方法
public static void printClassMessage(Object obj){
//要获取类的信息,首先要获取类的类类型
Class<?> class1 = obj.getClass();//传递的是哪个子类的对象,class1就是该子类的类类型
//获取类的名称
System.out.println(class1.getName());
/*
* Method类,方法对象(方法也是一种对象)
* 一个成员方法就是一个Method对象
* getMethods方法获取的是所有的public 的鼾声,包括父类继承而来的
* getDeclareMethods()获取的是所有该类自己声明的方法,不问访问权限,不包括继承来的方法
*/
Method[] methods = class1.getMethods();
for(int i = 0; i<methods.length; i++){
//得到方法的返回类型,得到的是返回值的类类型
Class<?> returnType = methods[i].getReturnType();
System.out.print(returnType.getName() + " ");
//得到方法的名称
System.out.print(methods[i].getName()+"(");
//获取参数类型-->得到的是参数的类类型
Class<?>[] paramTypes = methods[i].getParameterTypes();
for (Class<?> c : paramTypes) {
System.out.print(c.getName()+", ");
}
System.out.println(")");
}
}
//获取属性
public static void printFieldMessage(Object obj) {
/*
* 成员变量也是对象
* java.lang.reflect.Field
* Field类封装了关于成员变量的操作
* getFields()方法获取的是所有public的成员变量的信息
* getDeclaredFields()获取的是该类自己声明的成员变量的信息
*/
Class class1 = obj.getClass();
Field[] fields = class1.getDeclaredFields();
for (Field field : fields) {
//得到成员变量的类类型
Class fieldType = field.getType();
String typeName = fieldType.getName();
String fieldName = field.getName();
System.out.println(typeName + " " + fieldName);
}
}
/*
* 打印构造函数的信息
*/
public static void printConMessage(Object obj) {
Class class1 = obj.getClass();
/*
* 构造函数也是对象
* java.lang.Constructor中封装了构造函数的信息
* getConstructors获取所有的public构造函数
* getDeclaredConstructors获取所有的构造函数
*/
Constructor<?>[] cs = class1.getDeclaredConstructors();
for (Constructor<?> constructor : cs) {
System.out.print(constructor.getName() + "(");
Class<?>[] params = constructor.getParameterTypes();
for(Class<?> param : params) {
System.out.print(param.getName() + ", ");
}
System.out.println(")");
}
}
/*
*
*/
public static void useMethod() {
//要获取print(int, int)方法
//1 要获取一个方法就是获取类的信息,获取类的信息首先要获取类类型
A a1 = new ClassUtil.A();
Class<?> c = a1.getClass();
/*
* 2 获取方法名称和参数类比
*/
try {
//Method m = c.getMethod("print", new  Class<?>[]{int.class, int.class});
Method m = c.getMethod("print", int.class, int.class);
//Object o代表方法的返回值,如果没有返回值则是null,如果有返回值则是具体的返回值
Object o = m.invoke(a1, new Object[]{10,20});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static class A{
public void print(int a, int b) {
System.out.println(a+b);
}
public void print(String a, String b) {
System.out.println(a.toUpperCase() + "," + b.toLowerCase());
}
}

public static void main(String[] args){
try {
//反射的动态记载和DLL的动态记载类似,但是更强大,可以通过字符串来获得类、方法、属性
//动态加载类,在运行时刻加载
Class<?> class1 = Class.forName(args[0]);
//通过类类型,创建该类对象
IClassUtil util = (IClassUtil) class1.newInstance();
util.start();
//String string = "";
//printClassMessage(string);
//printFieldMessage(string);
//printConMessage(string);
useMethod();
//tttt();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public static void tttt(){
Class<?> class1 = int.class;//int的类类型
Class<?> class2 = String.class;
System.out.println(class1.getName());
System.out.println(class2.getName());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: