Java基础学习-反射

Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。

  反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。

  Java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,称为Java类的“自审”。

  Class类

       要正确使用Java反射机制就得使用java.lang.Class这个类。它是Java反射机制的起源。当一个类被加载以后,Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方法、成员以及构造方法的声明和定义等信息。

  反射API

       反射API用于反应在当前Java虚拟机中的类、接口或者对象信息

  功能

  [1] 获取一个对象的类信息.

       [2]获取一个类的访问修饰符、成员、方法、构造方法以及超类的信息.

       [3]检获属于一个接口的常量和方法声明.

      [4]创建一个直到程序运行期间才知道名字的类的实例.

     [5] 获取并设置一个对象的成员,甚至这个成员的名字是在程序运行期间才知道.

      [6] 检测一个在运行期间才知道名字的对象的方法

  

  使用反射机制的步骤:

  • 导入java.lang.relfect 包
  • 遵循三个步骤

   第一步是获得你想操作的类的 java.lang.Class 对象
   第二步是调用诸如 getDeclaredMethods 的方法
   第三步使用 反射API 来操作这些信息

       

  

获取Class对象的三种方式:

        加载XX.class文件进内存时就被封装成了对象,该对象就是字节码文件对象。如何获取Class对象呢?

  方式一:

        通过对象的getClass方法进行获取。

        如:Class clazz=new Person().getClass();//Person是一个类名

        麻烦之处:每次都需要具体的类和该类的对象,以及调用getClass方法。

  方式二:

        任何数据类型都具备着一个静态的属性class,这个属性直接获取到该类型的对应Class对象。

        如:Class clazz=Person.class;//Person是一个类名

        比第一种较为简单,不用创建对象,不用调用getClass方法,但是还是要使用具体的类,和该类中的一个静态属性class完成。

  方式三:

        这种方式较为简单,只要知道类的名称即可。不需要使用该类,也不需要去调用具体的属性和行为。就可以获取到Class对象了。

        如:Class clazz=Class.forName("包名.Person");//Person是一个类名

        这种方式仅知道类名就可以获取到该类字节码对象的方式,更有利于扩展。

  

  以下是一个反射小练习:

  

 1 package com.itheima.test;
 2 
 3 import java.lang.reflect.Constructor;
 4 class Test {
 5     
 6 }
 7 public class Demo5 {
 8     public static void main(String[] args) throws Exception{
 9     /*通过对象取得包名和类名*/
10         Test t = new Test();
11         System.out.println(t.getClass());
12         System.out.println(t.getClass().getName());
13 
14     /*Class类的实例化*/
15         //方式一:
16         Class<? extends Test> c1 = t.getClass();
17         System.out.println(c1);
18          
19         //方式二:
20         //为了避免特殊性,这里不用Test类,而用java库中的String类
21         Class<String> c2 = String.class;
22         System.out.println(c2);
23          
24         //方式三:
25         //forName()方法会抛出异常
26         Class<?> c3 = null;
27         try {
28             c3 = Class.forName("Test");
29         } catch (ClassNotFoundException e) {
30             e.printStackTrace();
31         }
32         System.out.println(c3);
33 
34     /*Class类的无参构造对象*/
35          //实例化Class对象,forName()方法会抛异常
36         Class<?> c = null;
37         try {
38             //这里需要完整的包名和类名
39             c = Class.forName("java.lang.String");
40         } catch (ClassNotFoundException e) {
41             e.printStackTrace();
42         }
43          
44         //生成一个字符串的引用
45         String s = null;
46         try {
47             //将构造好的对象向下转型为String类
48             //newInstance()方法会抛异常
49             s = (String) c.newInstance();
50         } catch (InstantiationException e) {
51             e.printStackTrace();
52         } catch (IllegalAccessException e) {
53             e.printStackTrace();
54         }
55         System.out.println("字符串长度: " + s.length());
56     /*Class类的有参构造对象*/
57         
58         Class<?> cc = null;
59         try {
60             cc = Class.forName("java.lang.String");
61         } catch (ClassNotFoundException e) {
62             e.printStackTrace();
63         }
64         char[] ch = {'h','e','i','m','a'};
65         String ss = null;
66         //获得Class类对象的有参构造方法,括号里面参数的写法是:类型.class
67         Constructor<?> con = cc.getConstructor(char[].class);
68         //用此构造方法构造一个新的字符串对象,参数为一个char数组
69         ss = (String) con.newInstance(ch);
70         System.out.println("构造的字符串:" + ss);        //获得构造的字符串:heima
71 
72     }
73 }
原文地址:https://www.cnblogs.com/soongkun/p/4885485.html