• java反射初学习


    java反射初学习

    “程序运行时,允许改变程序结构或变量类型,这种语

    言称为动态语言”,如Python,Ruby是动态语言;显然

    C++,Java,C#不是动态语言,但是JAVA有着一个非常

    突出的动态相关机制:Reflection。

    JAVA反射机制是在运行状态中,对于任意一个类,都能

    够知道这个类的所有属性和方法;对于任意一个对象,

    都能够调用它的任意一个方法和属性;这种动态获取的

    信息以及动态调用对象的方法的功能称为java语言的反

    射机制,很多优秀的开源框架都是通过反射完成的。

    Java反射机制,可以实现以下功能:

    ①在运行时判断任意一个对象所属的类;

    ②在运行时构造任意一个类的对象;

    ③在运行时判断任意一个类所具有的成员变量和方法;

    ④在运行时调用任意一个对象的方法;

    ⑤生成动态代理;

    可变参数

    /**
    
    * 入门级示例:通过对象获取 包名.类名 
    
    * @author Administrator 
    
    */ 
    
    public class Simple { 
    
    public static void main(String[] args) { 
    
    Simple s=new Simple(); 
    
    System.out.println(s.2.getName()); 
    
    } 
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    当我们能够确定一系列参数的类型,类型必须是统一

    的, 但是我们确定不了参数的个数的时候,我们可以使

    用可变参数。可变代表个数可变[0,+),如果一个方法

    中带有可变参数,这个可变参数只能在参数列表最后。

    获取源头Class(重点)

    所有类的对象其实都是Class**的实例。**这个 Class 实例

    可以理解为类的模子,就是包含了类的结构信息,类似

    于图纸。我们日常生活中,需要创造一个产品,如想山

    寨一个iphone手机,怎么办?有三种方式可以实现:

    ⑴买个iphone手机,拆的七零八落的,开始山寨;

    ⑵到iphone工厂参观,拿到iphone磨具,开始山寨;

    ⑶跑到美国盗取iphone的图纸,开始山寨,最后一种最

    暴力,最爽。

    同理,获取类的Class对象也有三种方式

    ⑴Class.forName(”包名.类名”) //一般尽量采用该形式

    (2)类.class

    (3)对象.getClass()

    类加载器(了解)

    类的生命周期

    在一个类编译完成之后,下一步就需要开始使用类,如

    果要使用一个类,肯定离不开JVM。在程序执行中JVM通

    过装载,链接,初始化这3个步骤完成。

    从类的生命周期而言,一个类包括如下阶段:

    加载、验证、准备、初始化和卸载这5个阶段的顺序是确

    定的,类的加载过程必须按照这种顺序进行

    类的装载 是通过 类加载器 完成的,加载器将 .class 文

    件的二进制文件装入JVM的方法区,并且在堆区创建描

    述这个类的 java.lang.Class 对象。用来封装数据。

    但是同一个类只会被类装载器装载一次。

    链接 就是把二进制数据组装为可以运行的状态。链接分

    为校验,准备,解析这3个阶段

    类加载器

    顾名思义,类加载器(class loader)用来加载 Java 类到

    Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的

    方式如下:Java 源程序(.java 文件)在经过 Java 编译

    器编译之后就被转换成 Java 字节代码(.class 文件)。

    类加载器负责读取 Java 字节代码,并转换成

    java.lang.Class 类的一个实例。每个这样的实例用

    来表示一个 Java 类。通过此实例的 newInstance()

    方法就可以创建出该类的一个对象。实际的情况可能更

    加复杂,比如 Java 字节代码可能是通过工具动态生成

    的,也可能是通过网络下载的。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f173Onk3-1603201534777)(C:UserslwfAppDataRoamingTypora ypora-user-imagesimage-20201020214106170.png)]

    在java中有三种类类加载器:

    ⑴ Bootstrap ClassLoader 此加载器采用c++编写,一般开

    发中很少见。⑵ Extension ClassLoader 用来进行扩展类的加载,一般

    对应的是jrelibext目录中的类

    ⑶ AppClassLoader 加载classpath指定的类,是最常用的

    加载器。同时也是java中默认的加载器。 了解即可。

    public static void main(String[] args) throws 
    
    Exception { 
    
    System.out.println("类加载器 
    
    "+ClassLoader.class.getClassLoader().getClass( 
    
    ).getName()); 
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    反射的运用

    package com.lwf;
    
    import java.io.*;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * @author lwf
     * @title: RefTest
     * @projectName Learn
     * @description: 反射
     * @date 2020/10/2019:51
     */
    public class RefTest {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, CloneNotSupportedException, IOException, NoSuchFieldException {
            //new对象
            Student student0=new Student();
            student0.setName("lwf");
            student0.setAge(18);
            student0.setClassName("class 1");
            System.out.println(student0);
            Class  c=Class.forName("com.lwf.Student");
            Constructor[] constructors = c.getDeclaredConstructors();
            for(Constructor c1 : constructors){
                System.out.println(c1);
            }
            Field[] declaredFields = c.getDeclaredFields();
            System.out.println("属性");
            for(Field field:declaredFields){
                System.out.println(field.getName()+","+field.getType());
            }
            //修改访问权限,将私有属性直接修改值
            Field field = c.getDeclaredField("name");
            field.setAccessible(true);
            field.set(student0, "罗卫飞");
            System.out.println(student0);
            //调用方法
            Method method=c.getMethod("getName");
            System.out.println(method.invoke(student0));
    
    
            //反射获取对象
            Student student1= (Student)c.getConstructor(String.class,Integer.class,String.class).newInstance("lwf",18,"一班");
            Student student= (Student)c.getConstructor().newInstance();
            System.out.println(student);
            System.out.println(student1);
    
    
    
            //克隆对象 继承Coneable接口
            Student student2=(Student)student1.clone();
            System.out.println(student2);
    
            //序列化获取对象
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("1.txt"));
            outputStream.writeObject(student);
            ObjectInputStream obj=new ObjectInputStream(new FileInputStream("1.txt"));
            Student object =(Student) obj.readObject();
            System.out.println(object);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    1. 构造器 :

      //反射获取对象
                 Student student1= (Student)c.getConstructor(String.class,Integer.class,String.class).newInstance("lwf",18,"一班");
                 Student student= (Student)c.getConstructor().newInstance();
       
      
      • 1
      • 2
      • 3
      • 4
    2. 获取属性并赋值

       //修改访问权限,将私有属性直接修改值
              Field field = c.getDeclaredField("name");//从所有属性中找;getField从public修饰属性中找属性
              field.setAccessible(true);
              field.set(student0, "罗卫飞");
              System.out.println(student0);
      
      • 1
      • 2
      • 3
      • 4
      • 5
    3. 获取方法并执行 Method对象调用invoke(实例,方法参数列表)

      //调用方法
              Method method=c.getMethod("getName");
              System.out.println(method.invoke(student0));
      
      • 1
      • 2
      • 3

    联系:对象的创建

    //new对象
            Student student0=new Student();
    
    
    //反射获取对象
            Student student1= (Student)c.getConstructor(String.class,Integer.class,String.class).newInstance("lwf",18,"一班");
            Student student= (Student)c.getConstructor().newInstance();
            System.out.println(student);
            System.out.println(student1);
            
       //克隆对象 继承Coneable接口
        Student student2=(Student)student1.clone();
        System.out.println(student2);
    
        //序列化获取对象
        ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("1.txt"));
        outputStream.writeObject(student);
        ObjectInputStream obj=new ObjectInputStream(new FileInputStream("1.txt"));
        Student object =(Student) obj.readObject();
  • 相关阅读:
    定时任务,执行时间动态配置方式
    MultipartFile+nio上传文件
    org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundaryRAYPKeHKTYSNdzc1;charset=UTF-8' not supported
    JDBC 连Sql Server 接数据库--The TCP/IP connection to the host localhost, port 1433 has failed
    swagger2常用注解说明
    java zxing实现二维码生成和解析zxing实现二维码生成和解析
    【springboot+easypoi】一行代码搞定excel导入导出
    linux中set、unset、export、env、declare,readonly的区别以及用法
    Spring---七大核心模块
    【Tomcat】Tomcat容器 web.xml详解
  • 原文地址:https://www.cnblogs.com/5118svip/p/13851651.html
Copyright © 2020-2023  润新知