zoukankan      html  css  js  c++  java
  • 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 }

     

    不积跬步无以至千里
  • 相关阅读:
    STL源码剖析之_allocate函数
    PAT 1018. Public Bike Management
    PAT 1016. Phone Bills
    PAT 1012. The Best Rank
    PAT 1014. Waiting in Line
    PAT 1026. Table Tennis
    PAT 1017. Queueing at Bank
    STL源码剖析之list的sort函数实现
    吃到鸡蛋好吃,看看是哪只母鸡下的蛋:好用的Sqlite3
    cJSON
  • 原文地址:https://www.cnblogs.com/wihainan/p/4759409.html
Copyright © 2011-2022 走看看