• Java reflect 反射 1


    1 反射的概述

    反射含义:可以获取正在运行的Java对象。

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

    对于任意一个对象,都能够调用它的任意一个方法;

    这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.

    反射就是让你可以通过名称来得到对象(类,属性,方法)的技术。

    例如我们可以通过类名来生成一个类的实例, 知道了方法名,就可以调用这个方法; 知道了属性名就可以访问这个属性的值

     

    • Java反射的功能

      1)可以判断运行时对象所属的类

      2)可以判断运行时对象所具有的成员变量和方法

      3)通过反射甚至可以调用到private的方法

      4)生成动态代理

     

    • 反射用在哪里

    反射是Java的高级特性,在框架中大量被使用!我们必须要了解反射,不然无法学好JavaWeb相关的知识!

    到底框架是什么?  框架就是将开发中大量重复的代码集中起来写个通用的程序

    框架就是用反射来实现的

    框架需要现在的类调用将来写的类

    框架是将来的程序员调用的,框架不能实现完整的功能,框架只是一些一些通用的代码

    框架要运行一定会依赖将来写的类

    现在写的类要调用将来写的类,我们先针对接口进行调用,将来的类需要实现接口,那么方法就固定了

    但是将来写的类的类名我们无法获知,这时就需要调用者通过配置文件告诉框架具体的类

    2 反射相关类

    l  Class: 表示类;

    l  Field: 表示成员变量;

    l  Method:表示方法;

    l  Constructor:表示构造器。

    注意:与反射相关的类们,它们都不能new!!!

    1)Class:它表示正在运行的Java应用程序中的类和接口

    2)Field:提供有关类或接口的属性信息,以及对它的动态访问权限

    3)Constructor:提供关于类的单个构造方法的信息以及对它的访问权限

    4)Method:提供关于类或接口中某个方法信息

    注意:Class类是Java反射中最重要的一个功能类,所有获取对象的信息(包括:方法/属性/构造方法/访问权限)都需要它来实现

     

     

    3 Class 类

    要想解剖一个类,必须先要获取到该类的字节码文件对象-->Class的对象。

    而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

     

    一段java代码在程序运行期间会经历三个阶段: source(*.class)-->class-->runtime

    每个.class文件被加载到内存后都是一个Class类的对象!例如Demo.class加载到内存后它是Class<Demo>类型的一个对象。

    在java中用一个Class对象来表示一个java类的class阶段

     

       学生有什么: ID   姓名 班级          用student类描述

       类有什么  : 成员 方法 构造方法     用Class类描述

     

    Class对象封装了一个java类中定义的成员变量、成员方法、构造方法、类名、包名等

    同时 成员变量 成员方法 构造方法 也有用于描述各自特点的类

    Class类:

     *     成员变量    Field

     *     构造方法    Constructor

     *     成员方法    Method

    3.1理解Class类

    Person.class(描述所有和李四类似的事物的信息) ----> Person对象 ----->李四(赵六、王五)

    Class.class(描述字节码这类事物的特征) –> Class对象—> Person.class字节码(Student.class Boy.class String.class)

    所有的Person对象能做的事情都用方法来描述,例如跑步用run方法描述

    所有的Class对象(字节码)能做的事情用方法来描述,例如创建对象用newInstance来描述

    对象都是根据类创建出来的—>创建一个对象代表李四这个人—>李四(跑起来)

    一个Class对象就表示一个.class文件,可以通过Class对象获取这个类的构造器、方法,以及成员变量等。

    3.2获取Class类

    1 不能通过new的方法获取Class的对象,因为构造方法是private   与反射有关的类均是如此

      public final class Class<T>  {

          private Class() {}

      }

    2 获取Class类的三种基本方式:

    类名.class

    对象.getClass()

    Class.forName(“字符串:类名”)

    l  通过类名称.class,对基本类型也支持;在java中所有的类型都会对应一个Class对象

    • Class c = int.class;
    • Class c = int[].class;
    • Class c = String.class

    l  通过对象.getClass()方法

    • Class c = obj.getClass();

    Class.forName()通过类名称加载类,这种方法只要有类名称就可以得到Class;

    • Class c = Class.forName(“cn.jt.Demo”);

     示例

    // 方式1

    Person p = new Person();

    Class c = p.getClass();

    Person p2 = new Person();

    Class c2 = p2.getClass();

    System.out.println(p == p2);// false

    System.out.println(c == c2);// true

    // 方式2

    Class c3 = Person.class;

    // int.class;

    // String.class;

    System.out.println(c == c3);

    // 方式3

    Class c4 = Class.forName("cn.jt.Person");

    System.out.println(c == c4);

    4 Class类的常用方法

    l  String getName():获取类名称,包含包名;

    l  String getSimpleName():获取类名称,不包含包名;

    l  Class getSupperClass():获取父类的Class,

                                   例如:new Integer(100).getClass().getSupperClass()返回的是Class<Number>!

                                   但new Object().getSupperClass()返回的是null,因为Object没有父类;

    l  T newInstance():使用本类无参构造器来创建本类对象;

    l  boolean isArray():是否为数组类型;

    l  boolean isAnnotation():是否为注解类型;

    l  boolean isAnnotationPresent(Class annotationClass):当前类是否被annotationClass注解了;

    l  boolean isEnum():是否为枚举类型;

    l  boolean isInterface():是否为接口类型;

    l  boolean isPrimitive():是否为基本类型;

    l  boolean isSynthetic():是否为引用类型;

    其他如获取Method Field Constructor的方法 见后面

    练习 :通过反射创建对象

     1 public class Demo1 {
     2 
     3     @Test
     4 
     5     public void fun1() throws Exception {
     6 
     7        String className = "cn.itcast.User";
     8 
     9        Class clazz = Class.forName(className);
    10 
    11        User user = (User)clazz.newInstance();
    12 
    13        System.out.println(user);
    14 
    15     }
    16 
    17 }
    18 
    19 class User {
    20 
    21     private String username;
    22 
    23     private String password;
    24 
    25  
    26 
    27     public String getUsername() {
    28 
    29        return username;
    30 
    31     }        
    32 
    33     public void setUsername(String username) {
    34 
    35        this.username = username;
    36 
    37     }
    38 
    39                   
    40 
    41     public String getPassword() {
    42 
    43        return password;
    44 
    45     }
    46 
    47  
    48 
    49     public void setPassword(String password) {
    50 
    51        this.password = password;
    52 
    53     }
    54 
    55  
    56 
    57     @Override
    58 
    59     public String toString() {
    60 
    61        return "User [username=" + username + ", password=" + password + "]";
    62 
    63     }
    64 
    65 }
    66 //结果
    67 User [username=null, password=null]

    练习:打印继承链

     

    1 Class clazz = JFrame.class;
    2 
    3 System.out.println(class.getName());
    4 
    5 for(Class superClass = clazz.getSuperclass();superClass!=null;System.out.println(supperClass.getName())){
    6 
    7 }

     

    不积跬步无以至千里
  • 相关阅读:
    在线学习Java免费资源推荐
    pycharm控制台输出乱码
    服务器质检文件传输——scp
    git使用小结
    更换python依赖包的下载路径
    查看某一时间段的cpu使用情况,sar(监控系统性能)
    运行脚本:‘$’ ’: 未找到命令’错误
    bash脚本,获取当前日期或时间作为参数
    installing new crontab-添加调度任务成功
    Mysql-删除数据表-三种方式详解
  • 原文地址:https://www.cnblogs.com/wihainan/p/4759409.html
Copyright © 2020-2023  润新知