Java反射机制--笔记

1、认识Class类

任何一个类都是Class类的实例对象,这个实例对象有三种表示方式。

         /*java 反射机制*/
// 获取类的方法
UserDao userDao = new UserDao();
Class c = UserDao.class; // 1、知道类名 使用.class获取类
Class d = userDao.getClass(); // 2、知道对象 使用.getClass()获取类
Class m = null; // 3、知道类 使用class.forName("")获取类
try {
m = Class.forName("com.description.dao.UserDao");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} System.out.println("c d是否相等 : " + (c==d));
System.out.println("c m是否相等 : " + (c==m)); try {
UserDao ud = (UserDao) c.newInstance(); // 通过反射实例化一个对象,前提是UserDao必须有一个默认的无参构造方法
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

2、动态加载类实例

新建四个类,一个Software接口,另外新建两个类继承该接口。

Software.java

 package com.hua.reflect;

 /**
* Created by 华天 on 2016/06/06.
*/
public interface Software {
public void show();
}

Word.java

 package com.hua.reflect;

 /**
* Created by 华天 on 2016/06/06.
*/
public class Word implements Software{ @Override
public void show() {
System.out.println("实现wold功能");
}
}

Excel.java

 package com.hua.reflect;

 /**
* Created by HuaTian on 2016/06/06.
*/
public class Excle implements Software {
@Override
public void show() {
System.out.println("实现Excel功能");
}
}

JavaReflect.java

  /**
* 动态加载类
*/
public static void getClass(String className) {
Software software = null;
try {
Class c = Class.forName("com.hua.reflect."+className);// 获取类
software = (Software) c.newInstance(); // 实例化类
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
software.show(); }
public static void main(String[] args){ /**
* 编译加载类属于静态加载类,运行加载类属于动态加载类
* new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。
* 通过使用动态加载类,类在使用时加载,不使用不加载。
*
*/
JavaReflect.getClass("Word");

知识点:

  1、编译加载类属于静态加载类,运行加载类属于动态加载类。

  2、new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。

  3、通过使用动态加载类,类在使用时加载,不使用不加载。

  4、void 等关键字都有类类型。

  5、获取类类型后就能获取类的相关信息。

  6、反射的操作都是编译后的操作。

  7、Java中的泛型是防止错误输入的,只在编译时期有效。ArrayList<String>  == ArrayList

      编译完成后泛型就不存在了,反射可以绕过编译将信息添加进去。

3、获取类中的相关信息

  新建一个ClassUtil.java 帮助类

 /**
* Created by 10113513 on 2016/06/06.
*/
public class ClassUtil { /**
* 显示类的相关信息
* @param obj
*/
public static void classMessage(Object obj) {
Class cs = obj.getClass();
System.out.println("类的全名称----------->" + cs.getName());
System.out.println("类的简写名称--------->" + cs.getSimpleName());
} /**
* 显示类中声明的方法
* @param obj
*/
public static void getMethods(Object obj){
Class cs = obj.getClass();
System.out.println("-------"+cs.getName()+"类中的方法");
Method[] methods = cs.getDeclaredMethods();
String show;
for (Method md : methods) {
show = md.getName() + md.getReturnType() + "(";
Class[] paramType = md.getParameterTypes();
for (Class c : paramType) {
show += c.getSimpleName() + ",";
}
show +=")";
System.out.println(show);
}
} /**
* 获取类的成员变量
* 只能获取公有的成员变量
* @param obj
*/
public static void getFiled(Object obj){
Class cs = obj.getClass();
System.out.println("-------"+cs.getName()+"类中的成员变量--------");
Field[] fds = cs.getFields();
for (Field fd:fds) {
System.out.println(fd.getName());
}
} /**
* 获取类中的构造函数
* @param obj
*/
public static void getConstructor(Object obj){
Class cs = obj.getClass();
System.out.println("-------"+cs.getName()+"类中的构造函数");
Constructor[] ctrs = cs.getConstructors();
String show = "";
for (Constructor ctr:ctrs) {
show += ctr.getName()+"(";
Parameter[] pars = ctr.getParameters();
for (Parameter par:pars) {
show += par.getName()+",";
}
show +=")";
System.out.println(show);
}
} }

4、获取方法的相关信息(获取的public的方法)

  1>方法名和参数列表决定了方法的唯一性

  2>方法反射的操作,method.invoke(对象,参数列表)

    1>> 方法没有返回值返回null,又返回值返回具体返回值。

    2>> 方法有参数列表就写成method.invoke(a1,int.class,int.class)  两个参数为例,

       没有参数直接写成method.invoke(a1,int.class,int.class) 。

5、整体代码

JavaReflect.java

 package com.hua.reflect;

 import com.description.dao.UserDao;

 /**
* Created by 华天 on 2016/06/06.
*/
public class JavaReflect {
public String animal;
private int num;
protected boolean isOk; public JavaReflect(){ }
public JavaReflect(String a){
System.out.println("do someThing");
} /**
* 动态加载类
* @param className
*/
public static void getClasses(String className) {
Software software = null;
try {
Class c = Class.forName("com.hua.reflect." + className);// 获取类
software = (Software) c.newInstance(); // 实例化类
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
software.show(); } /**
* 测试
* @param str
*/
public void test(String str) {
System.out.println("这是全部大写的测试方法:"+str.toUpperCase());
}
/**
* 测试1
*/
public void test1() {
System.out.println("这是全部小写的测试方法:"+"LIuBaoHua".toLowerCase());
} public static void main(String[] args) {
/*java 反射机制*/
// 获取类的方法
UserDao userDao = new UserDao();
Class c = UserDao.class; // 1、知道类名 .class
Class d = userDao.getClass(); // 2、知道对象 .getClass()
Class m = null; // 3、知道类的路径直接 class.forName("");
try {
m = Class.forName("com.description.dao.UserDao"); // 动态加载类
} catch (ClassNotFoundException e) {
e.printStackTrace();
} System.out.println("c d是否相等 : " + (c == d));
System.out.println("c m是否相等 : " + (c == m));
System.out.println("打印类名称:\n" + c.getName() + "\n" + d.getName() + "\n" + m.getName());
System.out.println("不包含包名的类名称:\n" + c.getSimpleName() + "\n" + d.getSimpleName()+ "\n" + m.getSimpleName()); try { UserDao ud = (UserDao) c.newInstance(); // 通过反射实例化一个对象,前提是UserDao必须有一个默认的无参构造方法
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
/**
* 1、编译加载类属于静态加载类,运行加载类属于动态加载类
* 2、new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。
* 3、通过使用动态加载类,类在使用时加载,不使用不加载。
* 4、void 等关键字都有类类型
* 5、获取类类型后就能获取类的相关信息
*/
JavaReflect.getClasses("Word"); ClassUtil.classMessage(new JavaReflect()); ClassUtil.getMethods(new JavaReflect()); ClassUtil.getFiled(new JavaReflect()); ClassUtil.getConstructor(new JavaReflect()); // 参数列表
Class[] parms = new Class[]{String.class};
String[] strs = new String[]{"liubaohua"};
// 测试有参数
ClassUtil.getMethod(new JavaReflect(),"test",parms,strs);
// 测试无参数
ClassUtil.getMethod(new JavaReflect(),"test1",null,null); } }

ClassUtil.java

 package com.hua.reflect;

 import java.lang.reflect.*;

 /**
* Created by 华天 on 2016/06/06.
*/
public class ClassUtil { /**
* 显示类的相关信息
* @param obj
*/
public static void classMessage(Object obj) {
Class cs = obj.getClass();
System.out.println("类的全名称----------->" + cs.getName());
System.out.println("类的简写名称--------->" + cs.getSimpleName());
} /**
* 显示类中声明的方法
* @param obj
*/
public static void getMethods(Object obj){
Class cs = obj.getClass();
System.out.println("-------"+cs.getName()+"类中的方法");
Method[] methods = cs.getDeclaredMethods();
String show;
for (Method md : methods) {
show = md.getName() + md.getReturnType() + "(";
Class[] paramType = md.getParameterTypes();
for (Class c : paramType) {
show += c.getSimpleName() + ",";
}
show +=")";
System.out.println(show);
}
} /**
* 获取类的成员变量
* 只能获取公有的成员变量
* @param obj
*/
public static void getFiled(Object obj){
Class cs = obj.getClass();
System.out.println("-------"+cs.getName()+"类中的成员变量--------");
Field[] fds = cs.getFields();
for (Field fd:fds) {
System.out.println(fd.getName());
}
} /**
* 获取类中的构造函数
* @param obj
*/
public static void getConstructor(Object obj){
Class cs = obj.getClass();
System.out.println("-------"+cs.getName()+"类中的构造函数");
Constructor[] ctrs = cs.getConstructors();
String show = "";
for (Constructor ctr:ctrs) {
show += ctr.getName()+"(";
Parameter[] pars = ctr.getParameters();
for (Parameter par:pars) {
show += par.getName()+",";
}
show +=")";
System.out.println(show);
}
} /**
* 获取特定的方法
* @param obj 类
* @param mdName 方法名
* @param parms 参数列表
* @param objs 传入参数
*/
public static void getMethod(Object obj,String mdName,Class[] parms,Object[] objs){
Class cs = obj.getClass();
System.out.println("----------"+cs.getName()+"类中的具体方操作------------");
try {
JavaReflect ncs = (JavaReflect) cs.newInstance();
// getDeclaredMethod(方法名,参数列表);
Method md = null;
if(parms == null){
md = cs.getDeclaredMethod(mdName);
// 调用方法
md.invoke(ncs);
}else{
md = cs.getDeclaredMethod(mdName,parms);
// 调用方法
md.invoke(ncs,objs);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} } }

  JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用

对象的方法的功能称为java语言的反射机制。

  

上一篇:(转)个例子让你了解Java反射机制


下一篇:(转)JAVA反射机制理解