码迷,mamicode.com
首页 > 其他好文 > 详细

第33天学习打卡(反射)

时间:2021-02-15 11:39:48      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:tps   姓名   需求   OLE   需要   成员   tee   使用   process   

反射概述

反射

在程序运行过程中分析类的一种能力。

反射能做什么:

分析类

加载并初始化一个类,查看类的所有属性和方法

查看并使用对象

查看一个对象的所有属性和方法使用对象的任意属性和方法

反射的应用场景

构建通用工具

搭建具有高度灵活性和扩展性的系统框架

类加载器(ClassLoader)

负责将类的字节码文件(.class文件)加载到内存中,并生成对应的Class对象。

Class对象

java.lang.Class类的对象,也加字节码文件对象,每个Class对象对应一个字节码文件。

技术图片

 

类的加载时机

创建类的实例
 Student stu = new Student();

一个类的字节码文件只会被加载一次

访问类的静态成员
 Calendar.getInstance();

先加载Calendar的字节码文件到内存

初始化类的子类
 class User extends Person{}
 User user = new Use();//先加载父类Person
反射方式创建类的Class对象
 Class clazz = Class.forName("类的正名")
     正名: 包名 + 类名,例如:cn.itcast.demo01.Student

获取Class对象的三种方式

Object类的getClass()方法:

 Class clazz = 对象名.getClass();

 

类的静态属性:

 Class clazz = 类名.class;

Class类的静态方法:

 Class clazz = Class.forName("类的正名")
 正名:包类路径名,如:cn.itcast.bean.Student

 

 package cn.itcast.demo29;
 /**
  * 获取Class对象(字节码文件对象)的三种方式
  *   1.Object类的getClass()方法
  *           Class clazz = 对象名.getClass();
  *   2.类的静态属性
  *           Class clazz = 类名.class
  *   3.Class类的静态方法
  *           Class clazz = Class.forName("类的正名");
  *           正名:包名 + 类名
  *
  *   注意:一个源文件(.java文件)对应一个字节码文件对象(.class)
  *
  */
 ?
 public class ReflectDemo01 {
     public static void main(String[] args) throws ClassNotFoundException {
         //需求:获取Class对象
         //方式一:
         Student stu = new Student();
         Class clazz1 = stu.getClass();
 ?
 ?
         //方式二:
         Class clazz2 = Student.class;
 ?
         //方式三
         Class clazz3 = Class.forName("cn.itcast.demo29.Student");
         System.out.println(clazz1 == clazz2);//输出结果为true
         System.out.println(clazz2 == clazz3);//输出结果为true
 ?
 ?
 ?
    }
 }
 ?

反射方式获取构造方法并使用

 

Constructor<T>对象

构造器对象,属于java.base模块,java.lang.reflect包

通过Class对象获取构造器对象

 getConstructor(Class<?>...parameterTypes)
                返回一个Constructor对象,仅公共构造参数
                Class<?>...:可变参数,代表Class类型的数组
                    ?:通配符,代表不确定的任意类型
                       
 getDeclaredConstructor(Class<?>...parameterTypes)
                        返回一个Constructor对象,可获取私有构造函数
 getConstructors()
                         返回此类所有(不含私有)构造函数的数组

 

Constructor的常用方法

 String getName()
           返回构造函数
 T newInstance(Object...initargs)
            使用此构造函数和指定参数创建并初始化对象

技术图片

 package cn.itcast.demo30;
 ?
 import java.lang.reflect.Constructor;
 ?
 /**
  *Class类
  *     成员方法:
  *           public Constructor getConstructor(Class...params);
  *                   根据参数列表,获取对应的构造器对象(仅限公共构造函数)
  *           public Constructor getDeclaredConstructor(Class...params);
  *                   根据参数列表,获取对应的构造器对象(包含私有构造函数)
  *           public Constructors[] getConstructors();获取此类所有的构造函数(不包含私有)
  *
  *   *Constructor类: 构造器类
  *         概述:属于java.base模块下的java.lang.reflect包下的类
  *
  *         成员方法:
  *         public String getName(); 获取构造函数名
  *         public T newInstances(Object...params); 根据此构造函数和指定参数创建对象
  */
 ?
 public class ReflectDemo01 {
     public static void main(String[] args) throws Exception {
         //需求:通过反射的方式创建:Student类型的对象
         //1.获取Student类的字节码文件对象
         Class clazz = Class.forName("cn.itcast.demo30.Student");
 ?
         //2.根据第一步获取到的字节码文件对象,获取指定的构造器对象
         //2.1获取公共的无参构造
         Constructor con1 = clazz.getConstructor();
         System.out.println(con1);
         //2.2获取公共的有参构造
 ?
         Constructor con2 = clazz.getConstructor(String.class);
         System.out.println(con2);
 ?
         //2.3获取私有的有参构造
         Constructor con3 = clazz.getDeclaredConstructor(int.class);
         System.out.println(con3);
 ?
         //2.4获取Student类的所有公共的构造函数
         System.out.println("=====================");
         Constructor[] cons = clazz.getConstructors();
 ?
         //遍历数组
         for(Constructor con : cons){
             System.out.println(con);
        }
 ?
         //3.根据构造器对象和参数,创建对应的Student对象
         //4.打印结果
 ?
    }
 }
 ?

输出结果:

D:\Java\JDK8\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA public cn.itcast.demo30.Student() public cn.itcast.demo30.Student(java.lang.String)

private cn.itcast.demo30.Student(int)

public cn.itcast.demo30.Student() public cn.itcast.demo30.Student(java.lang.String)

Process finished with exit code 0

 

 package cn.itcast.demo30;
 ?
 import java.lang.reflect.Constructor;
 ?
 /**
  *Class类
  *     成员方法:
  *           public Constructor getConstructor(Class...params);
  *                   根据参数列表,获取对应的构造器对象(仅限公共构造函数)
  *           public Constructor getDeclaredConstructor(Class...params);
  *                   根据参数列表,获取对应的构造器对象(包含私有构造函数)
  *           public Constructors[] getConstructors();获取此类所有的构造函数(不包含私有)
  *
  *   *Constructor类: 构造器类
  *         概述:属于java.base模块下的java.lang.reflect包下的类
  *
  *         成员方法:
  *         public String getName(); 获取构造函数名
  *         public T newInstances(Object...params); 根据此构造函数和指定参数创建对象
  */
 ?
 public class ReflectDemo01 {
     public static void main(String[] args) throws Exception {
         //需求:通过反射的方式创建:Student类型的对象
         //1.获取Student类的字节码文件对象
         Class clazz = Class.forName("cn.itcast.demo30.Student");
 ?
         //2.根据第一步获取到的字节码文件对象,获取指定的构造器对象
         /* //2.1获取公共的无参构造
         Constructor con1 = clazz.getConstructor();
         System.out.println(con1);
         //2.2获取公共的有参构造
 ?
         Constructor con2 = clazz.getConstructor(String.class);
         System.out.println(con2);
 ?
         //2.3获取私有的有参构造
         Constructor con3 = clazz.getDeclaredConstructor(int.class);
         System.out.println(con3);
 ?
         //2.4获取Student类的所有公共的构造函数
         System.out.println("=====================");
         Constructor[] cons = clazz.getConstructors();
 ?
         //遍历数组
         for(Constructor con : cons){
             System.out.println(con);
         }*/
         //2.2获取公共的有参构造
 ?
         Constructor con2 = clazz.getConstructor(String.class);
         System.out.println(con2);
         //获取构造器的名字,看看他是哪个类的构造
         String name = con2.getName();
         System.out.println(name);
 ?
         //3.根据构造器对象和参数,创建对应的Student对象
         Student stu = (Student) con2.newInstance("张三");
         System.out.println(stu);
         //4.打印结果
 ?
    }
 }
 ?

 

 package cn.itcast.demo30;
 //学生类
 public class Student {
     //公共的无参构造
     public Student(){
 ?
    }
     //公共的带参构造
     public Student(String name){
         System.out.println("您录入的name的值是: " + name);
 ?
    }
     //私有的带参构造
     private  Student(int age){
         System.out.println("您录入的age的值是: " + age);
    }
 }
 ?

输出结果:

public cn.itcast.demo30.Student(java.lang.String) cn.itcast.demo30.Student 您录入的name的值是: 张三 cn.itcast.demo30.Student@14ae5a5

反射方式获取成员方法并使用

 

Method对象

方法对象,属于java.base模块,java.lang.reflect包

通过Class对象获取方法

 getMethod(String name,Class<?>...parameterTypes)
           返回一个Method对象,仅公共成员方法
           neme:方法名
           parameterTypes:方法的参数列表
 getDeclaredMethod(String,Class<?>...)
            返回一个Method对象,可获取私有成员方法
 getMethods()
            返回此类所有(不含私有)的方法数组
       

Method的常用方法

 String getName()
         返回方法名
 Object invoke(Object obj, Object ...args)
         在指定对象上调用此方法,参数为args
         

技术图片

 

 package cn.itcast.demo31;
 ?
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 ?
 /**
  *Class类
  *     成员方法:
  *           public Method getMethod(String name,Class...params)
  *           返回一个Method对象,仅公共成员方法
  *           public Method getDeclaredMethod(String,Class...params)
  *           返回一个Method对象,可获取私有成员方法
  *           public Method[] getMethods()返回此类所有(不含私有)方法的数组
  *          
  *
  *   *Method类: 方法类
  *         概述:属于java.base模块下的java.lang.reflect包下的类
  *
  *         成员方法:
  *         public String getName(); 获取成员方法名
  *         public Object invoke(Object obj,Object...params); 调用指定方法,obj表示该类的对象,params表示调用该方法所需的参数
  *
  *         public void setAccessible(boolean flag):是否开启暴力反射(true:开启)
  */
 ?
 public class ReflectDemo01 {
     public static void main(String[] args) throws Exception {
         //需求:通过反射获取Student类中的成员方法并调用
         //1.获取Student类的字节码文件对象
         Class clazz = Class.forName("cn.itcast.demo31.Student");
         //2.获取该类的构造器对象,然后创建Student类的对象
         Constructor con = clazz.getConstructor();
         Student stu = (Student)con.newInstance();
        // System.out.println(stu);
 ?
         //3.获取该类的成员方法对象,然后调用此方法
         //3.1调用公共的空参构造
         Method method1 = clazz.getMethod("show1");
         //打印方法对象
         System.out.println(method1);
 ?
         //打印方法名
         System.out.println(method1.getName());
 ?
         //调用此方法
         method1.invoke(stu);//返回是void类型不需要变量进行接收
         System.out.println("==================");
         //3.2公共的带参方法
         Method method2 = clazz.getMethod("show2", int.class);
         //调用方法
         method2.invoke(stu,100);
 ?
 ?
         System.out.println("================");
         //3.3调用私有的带参方法
         Method method3 = clazz.getDeclaredMethod("show3", int.class, int.class);
         //开启暴力反射
         method3.setAccessible(true);
         //调用此方法
        int sum = (int) method3.invoke(stu,10,20);
         System.out.println("您录入的两个数的和是: " + sum);
         System.out.println("=====================");
 ?
         //3.4获取Student类中的所有的成员方法
         Method[] methods = clazz.getMethods();
         for(Method method : methods){
             System.out.println(method);
        }
 ?
 ?
 ?
    }
 }
 ?
 package cn.itcast.demo31;
 ?
 public class Student {
     //公共的空参方法
     public void show1(){
         System.out.println("我是公共的空参方法");
    }
     //公共的带参方法
     public void show2(int a){
         System.out.println("我是公共的带参方法,您传入的值是: " + a);
 ?
    }
     //私有的带参方法
     private int show3(int a, int b){
         System.out.println("我是私有的带参方法");
         return  a + b;
    }
 }
 ?

 

反射方式获取成员变量并使用

Filed 对象

域(属性、成员变量)对象,属于java.base模块

java.lang.reflect包

通过Class对象获取属性
 getField(String name)
         返回一个Filed对象,仅公共属性
         name:属性名
 getDeclaredField(String name)
         返回一个Filed对象,可获取私有属性
 getDeclaredFields()
         返回此类所有(含私有)属性的数组
         

Field的常用方法

 void set(Object obj,Object value)
          设置obj对象的指定属性值为value
         
 void setAccessible(boolean flag)
          将此属性的可访问性设置为指定布尔值

技术图片

 

 package cn.itcast.demo33;
 ?
 import java.io.File;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 ?
 /**
  * Class类
  *   成员方法:
  *         public Filed getField(String name)返回一个Field对象,仅公共成员变量
  *         public Field getField(String name)返回一个Field对象,可获取私有成员变量
  *         public Field[] getDeclaredFields() 返回此类所有(含私有)成员变量的数组
  *
  * Field: 属性类,用来表示所有域(属性, 成员变量)对象的。
  *       概述:属于java.base模块下的java.lang.reflect包下的类
  *
  *   成员方法:
  *   public void setAccessible(boolean flag)   是否开启暴力反射(true :开启)
  *   public void set(Object obj,Object value); 设置obj对象的指定属性值为value
  *
  */
 ?
 ?
 public class ReflectDemo01 {
     public static void main(String[] args) throws Exception {
         //需求:通过反射获取成员变量并使用
         //1.获取Student类的字节码文件对象
         Class clazz = Class.forName("cn.itcast.demo33.Student");
         //2.通过字节码文件对象获取构造器对象,然后创建学生类对象
         Constructor con = clazz.getConstructor();
         Student stu = (Student)con.newInstance();
         //这行代码是上述两行代码的合并写法
        // Student stu2 = (Student)clazz.getConstructor().newInstance();链式编程:方法返回值还是一个对象的时候还可以在后面.方法
         //3.设置学生对象的各个属性值
         //3.1设置姓名
         Field field1 = clazz.getField("name");
         field1.set(stu,"豆豆");
 ?
         //3.2设置年龄
         Field field2 = clazz.getDeclaredField("age");
         //开启暴力反射
         field2.setAccessible(true);
         field2.set(stu,18);
 ?
         //4.打印学生对象
         System.out.println(stu);
 ?
 ?
    }
 }
 ?

 

第33天学习打卡(反射)

标签:tps   姓名   需求   OLE   需要   成员   tee   使用   process   

原文地址:https://www.cnblogs.com/doudoutj/p/14395485.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!