Java反射机制--笔记

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

回到顶部