Java反射机制--笔记
1、认识Class类
任何一个类都是Class类的实例对象,这个实例对象有三种表示方式。
1 /*java 反射机制*/2 // 获取类的方法
3 UserDao userDao = new UserDao();
4 Class c = UserDao.class; // 1、知道类名 使用.class获取类
5 Class d = userDao.getClass(); // 2、知道对象 使用.getClass()获取类
6 Class m = null; // 3、知道类 使用class.forName("")获取类
7 try {
8 m = Class.forName("com.description.dao.UserDao");
9 } catch (ClassNotFoundException e) {
10 e.printStackTrace();
11 }
12
13 System.out.println("c d是否相等 : " + (c==d));
14 System.out.println("c m是否相等 : " + (c==m));
15
16 try {
17 UserDao ud = (UserDao) c.newInstance(); // 通过反射实例化一个对象,前提是UserDao必须有一个默认的无参构造方法
18 } catch (InstantiationException e) {
19 e.printStackTrace();
20 } catch (IllegalAccessException e) {
21 e.printStackTrace();
22 }
2、动态加载类实例
新建四个类,一个Software接口,另外新建两个类继承该接口。
Software.java
1 package com.hua.reflect;2
3 /**
4 * Created by 华天 on 2016/06/06.
5 */
6 public interface Software {
7 public void show();
8 }
View Code
Word.java
1 package com.hua.reflect;2
3 /**
4 * Created by 华天 on 2016/06/06.
5 */
6 public class Word implements Software{
7
8
9 @Override
10 public void show() {
11 System.out.println("实现wold功能");
12 }
13 }
View Code
Excel.java
1 package com.hua.reflect;2
3 /**
4 * Created by HuaTian on 2016/06/06.
5 */
6 public class Excle implements Software {
7 @Override
8 public void show() {
9 System.out.println("实现Excel功能");
10 }
11 }
View Code
JavaReflect.java
1 /**2 * 动态加载类
3 */
4 public static void getClass(String className) {
5 Software software = null;
6 try {
7 Class c = Class.forName("com.hua.reflect."+className);// 获取类
8 software = (Software) c.newInstance(); // 实例化类
9 } catch (ClassNotFoundException e) {
10 e.printStackTrace();
11 } catch (InstantiationException e) {
12 e.printStackTrace();
13 } catch (IllegalAccessException e) {
14 e.printStackTrace();
15 }
16 software.show();
17
18 }
19 public static void main(String[] args){
20
21 /**
22 * 编译加载类属于静态加载类,运行加载类属于动态加载类
23 * new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。
24 * 通过使用动态加载类,类在使用时加载,不使用不加载。
25 *
26 */
27 JavaReflect.getClass("Word");
View Code
知识点:
1、编译加载类属于静态加载类,运行加载类属于动态加载类。
2、new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。
3、通过使用动态加载类,类在使用时加载,不使用不加载。
4、void 等关键字都有类类型。
5、获取类类型后就能获取类的相关信息。
6、反射的操作都是编译后的操作。
7、Java中的泛型是防止错误输入的,只在编译时期有效。ArrayList<String> == ArrayList
编译完成后泛型就不存在了,反射可以绕过编译将信息添加进去。
3、获取类中的相关信息
新建一个ClassUtil.java 帮助类
1 /**2 * Created by 10113513 on 2016/06/06.
3 */
4 public class ClassUtil {
5
6 /**
7 * 显示类的相关信息
8 * @param obj
9 */
10 public static void classMessage(Object obj) {
11 Class cs = obj.getClass();
12 System.out.println("类的全名称----------->" + cs.getName());
13 System.out.println("类的简写名称--------->" + cs.getSimpleName());
14 }
15
16 /**
17 * 显示类中声明的方法
18 * @param obj
19 */
20 public static void getMethods(Object obj){
21 Class cs = obj.getClass();
22 System.out.println("-------"+cs.getName()+"类中的方法");
23 Method[] methods = cs.getDeclaredMethods();
24 String show;
25 for (Method md : methods) {
26 show = md.getName() + md.getReturnType() + "(";
27 Class[] paramType = md.getParameterTypes();
28 for (Class c : paramType) {
29 show += c.getSimpleName() + ",";
30 }
31 show +=")";
32 System.out.println(show);
33 }
34 }
35
36 /**
37 * 获取类的成员变量
38 * 只能获取公有的成员变量
39 * @param obj
40 */
41 public static void getFiled(Object obj){
42 Class cs = obj.getClass();
43 System.out.println("-------"+cs.getName()+"类中的成员变量--------");
44 Field[] fds = cs.getFields();
45 for (Field fd:fds) {
46 System.out.println(fd.getName());
47 }
48 }
49
50 /**
51 * 获取类中的构造函数
52 * @param obj
53 */
54 public static void getConstructor(Object obj){
55 Class cs = obj.getClass();
56 System.out.println("-------"+cs.getName()+"类中的构造函数");
57 Constructor[] ctrs = cs.getConstructors();
58 String show = "";
59 for (Constructor ctr:ctrs) {
60 show += ctr.getName()+"(";
61 Parameter[] pars = ctr.getParameters();
62 for (Parameter par:pars) {
63 show += par.getName()+",";
64 }
65 show +=")";
66 System.out.println(show);
67 }
68 }
69
70 }
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
1 package com.hua.reflect;2
3 import com.description.dao.UserDao;
4
5
6 /**
7 * Created by 华天 on 2016/06/06.
8 */
9 public class JavaReflect {
10 public String animal;
11 private int num;
12 protected boolean isOk;
13
14 public JavaReflect(){
15
16 }
17 public JavaReflect(String a){
18 System.out.println("do someThing");
19 }
20
21
22 /**
23 * 动态加载类
24 * @param className
25 */
26 public static void getClasses(String className) {
27 Software software = null;
28 try {
29 Class c = Class.forName("com.hua.reflect." + className);// 获取类
30 software = (Software) c.newInstance(); // 实例化类
31 } catch (ClassNotFoundException e) {
32 e.printStackTrace();
33 } catch (InstantiationException e) {
34 e.printStackTrace();
35 } catch (IllegalAccessException e) {
36 e.printStackTrace();
37 }
38 software.show();
39
40 }
41
42 /**
43 * 测试
44 * @param str
45 */
46 public void test(String str) {
47 System.out.println("这是全部大写的测试方法:"+str.toUpperCase());
48 }
49 /**
50 * 测试1
51 */
52 public void test1() {
53 System.out.println("这是全部小写的测试方法:"+"LIuBaoHua".toLowerCase());
54 }
55
56
57 public static void main(String[] args) {
58 /*java 反射机制*/
59 // 获取类的方法
60 UserDao userDao = new UserDao();
61 Class c = UserDao.class; // 1、知道类名 .class
62 Class d = userDao.getClass(); // 2、知道对象 .getClass()
63 Class m = null; // 3、知道类的路径直接 class.forName("");
64 try {
65 m = Class.forName("com.description.dao.UserDao"); // 动态加载类
66 } catch (ClassNotFoundException e) {
67 e.printStackTrace();
68 }
69
70 System.out.println("c d是否相等 : " + (c == d));
71 System.out.println("c m是否相等 : " + (c == m));
72 System.out.println("打印类名称:\n" + c.getName() + "\n" + d.getName() + "\n" + m.getName());
73 System.out.println("不包含包名的类名称:\n" + c.getSimpleName() + "\n" + d.getSimpleName()+ "\n" + m.getSimpleName());
74
75 try {
76
77 UserDao ud = (UserDao) c.newInstance(); // 通过反射实例化一个对象,前提是UserDao必须有一个默认的无参构造方法
78 } catch (InstantiationException e) {
79 e.printStackTrace();
80 } catch (IllegalAccessException e) {
81 e.printStackTrace();
82 }
83 /**
84 * 1、编译加载类属于静态加载类,运行加载类属于动态加载类
85 * 2、new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。
86 * 3、通过使用动态加载类,类在使用时加载,不使用不加载。
87 * 4、void 等关键字都有类类型
88 * 5、获取类类型后就能获取类的相关信息
89 */
90 JavaReflect.getClasses("Word");
91
92 ClassUtil.classMessage(new JavaReflect());
93
94 ClassUtil.getMethods(new JavaReflect());
95
96 ClassUtil.getFiled(new JavaReflect());
97
98 ClassUtil.getConstructor(new JavaReflect());
99
100 // 参数列表
101 Class[] parms = new Class[]{String.class};
102 String[] strs = new String[]{"liubaohua"};
103 // 测试有参数
104 ClassUtil.getMethod(new JavaReflect(),"test",parms,strs);
105 // 测试无参数
106 ClassUtil.getMethod(new JavaReflect(),"test1",null,null);
107
108 }
109
110
111 }
ClassUtil.java
1 package com.hua.reflect;2
3 import java.lang.reflect.*;
4
5 /**
6 * Created by 华天 on 2016/06/06.
7 */
8 public class ClassUtil {
9
10 /**
11 * 显示类的相关信息
12 * @param obj
13 */
14 public static void classMessage(Object obj) {
15 Class cs = obj.getClass();
16 System.out.println("类的全名称----------->" + cs.getName());
17 System.out.println("类的简写名称--------->" + cs.getSimpleName());
18 }
19
20 /**
21 * 显示类中声明的方法
22 * @param obj
23 */
24 public static void getMethods(Object obj){
25 Class cs = obj.getClass();
26 System.out.println("-------"+cs.getName()+"类中的方法");
27 Method[] methods = cs.getDeclaredMethods();
28 String show;
29 for (Method md : methods) {
30 show = md.getName() + md.getReturnType() + "(";
31 Class[] paramType = md.getParameterTypes();
32 for (Class c : paramType) {
33 show += c.getSimpleName() + ",";
34 }
35 show +=")";
36 System.out.println(show);
37 }
38 }
39
40 /**
41 * 获取类的成员变量
42 * 只能获取公有的成员变量
43 * @param obj
44 */
45 public static void getFiled(Object obj){
46 Class cs = obj.getClass();
47 System.out.println("-------"+cs.getName()+"类中的成员变量--------");
48 Field[] fds = cs.getFields();
49 for (Field fd:fds) {
50 System.out.println(fd.getName());
51 }
52 }
53
54 /**
55 * 获取类中的构造函数
56 * @param obj
57 */
58 public static void getConstructor(Object obj){
59 Class cs = obj.getClass();
60 System.out.println("-------"+cs.getName()+"类中的构造函数");
61 Constructor[] ctrs = cs.getConstructors();
62 String show = "";
63 for (Constructor ctr:ctrs) {
64 show += ctr.getName()+"(";
65 Parameter[] pars = ctr.getParameters();
66 for (Parameter par:pars) {
67 show += par.getName()+",";
68 }
69 show +=")";
70 System.out.println(show);
71 }
72 }
73
74 /**
75 * 获取特定的方法
76 * @param obj 类
77 * @param mdName 方法名
78 * @param parms 参数列表
79 * @param objs 传入参数
80 */
81 public static void getMethod(Object obj,String mdName,Class[] parms,Object[] objs){
82 Class cs = obj.getClass();
83 System.out.println("----------"+cs.getName()+"类中的具体方操作------------");
84 try {
85 JavaReflect ncs = (JavaReflect) cs.newInstance();
86 // getDeclaredMethod(方法名,参数列表);
87 Method md = null;
88 if(parms == null){
89 md = cs.getDeclaredMethod(mdName);
90 // 调用方法
91 md.invoke(ncs);
92 }else{
93 md = cs.getDeclaredMethod(mdName,parms);
94 // 调用方法
95 md.invoke(ncs,objs);
96 }
97 } catch (NoSuchMethodException e) {
98 e.printStackTrace();
99 } catch (InvocationTargetException e) {
100 e.printStackTrace();
101 } catch (IllegalAccessException e) {
102 e.printStackTrace();
103 } catch (InstantiationException e) {
104 e.printStackTrace();
105 }
106
107 }
108
109 }
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用
对象的方法的功能称为java语言的反射机制。
以上是 Java反射机制--笔记 的全部内容, 来源链接: utcz.com/z/394065.html