zoukankan      html  css  js  c++  java
  • Java反射机制的学习

    在学习java的spring框架时老是要与java的反射机制打交道,为止花了一些时间来了解java的反射机制。

    在创建数据库的jdbc也有遇到java的反射机制比如MySQL的JDBC,Class.forName("com.mysql*").

    一:Java的反射(reflection)是什么?

    我的一个大概的理解是:java反射是用来获取一个java类本身的一些信息,比如类里面声明的静态变量,实例变量,公有方法,私有方法。

    除此之外,反射机制还能帮我们获取,或者创建一个类的对象。

    Java的反射机制主要通过Java.lang.Class和Java.lang.reflect包下的API来实现的,而且java反射机制是与运行中的JVM打交道的。

    来看Oracle官方文档对反射机制的两种解释:

    解释一:

    Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, 
    and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security
    restrictions. The API accommodates applications that need access to either the public members of a target
    object (based on its runtime class) or the members declared by a given class. It also allows programs to
    suppress default reflective access control.

    解释二:

    Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself,
    and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members
    and display them.

    The ability to examine and manipulate a Java class from within itself may not sound like very much, but in other programming languages
    this feature simply doesn't exist. For example, there is no way in a Pascal, C, or C++ program to obtain information about the
    functions defined within that program.
    One tangible use of reflection is in JavaBeans, where software components can be manipulated visually via a builder tool.
    The tool uses reflection to obtain the properties of Java components (classes) as they are dynamically loaded.

    二: 示例

    先写一个java类

    package com.qa.reflection;
    
    public class Student {
        private String studentName;
        public int studentAge;
        public Student(){
            System.out.println("This is a public Constructor without arguments.");
        }
    
        private Student(String studentName){
            this.studentName=studentName;
            System.out.println("This is a private constructor with argument.");
        }
    
        public void setStudentAge(int studentAge) {
            this.studentAge = studentAge;
            System.out.println("This is a public method with argument, to set student Age.");
        }
    
        private String show(){
            System.out.println("This is a private method, show massage.");
            System.out.println("Show massage,student name:"+studentName+"--Student Age:"+studentAge);
            return "Show Method---------";
        }
    }

    上面的Student类里面既有public属性也有private属性

    既有public方法也有private方法.

    三:获取Class对象的三种方法

    // 1.通过字符串获取Class对象,这个字符串必须带上完整路径名
    Class studentClass = Class.forName("com.test.reflection.Student");
    // 2.通过类的class属性
    Class studentClass2 = Student.class;
    // 3.通过对象的getClass()函数
    Student studentObject = new Student();
    Class studentClass3 = studentObject.getClass();

    其运行结果如下:

    //以上三种获取Class对象的方法默认会调用无参数的构造方法
    //并且:我们用了三种方式去获取Class对象,但实际上生成的对象是同一个,这是单例模式。

    //注意这句输出结果,它表明反射机制默认调用了无参数构造方法。这句话是我们在编写Student()这个无参构造方法十加的。

    This is a public Constructor without arguments.
    查看Class的对象是否为同一个. Student Class1:
    class com.qa.reflection.Student Student Class2:class com.qa.reflection.Student Student Class3:class com.qa.reflection.Student Student Class1==Student Class2:true Student Class2==Student Class3:true

    以上三种获取Class对象的方法默认会调用无参数的构造方法
    并且:我们用了三种方式去获取Class对象,但实际上生成的对象是同一个,这是单例

    创建一个测试类

    package com.qa.reflection;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    /*
    反射类的操作
    */
    
    public class ReflectionTest {
    
        public static void main(String[] args) throws ClassNotFoundException {
            Class studentClass1 = Class.forName("com.qa.reflection.Student");
            Class studentClass2 =Student.class;
            Student stu=new Student();
            Class studentClass3=stu.getClass();
    
            System.out.println("查看Class的对象是否为同一个.");
            System.out.println("Student Class1:"+studentClass1.toString());
            System.out.println("Student Class2:"+studentClass2.toString());
            System.out.println("Student Class3:"+studentClass3.toString());
            System.out.println("Student Class1==Student Class2:"+(studentClass1==studentClass2));
            System.out.println("Student Class2==Student Class3:"+(studentClass2==studentClass3));
    
    //     1. Class.getDeclaredFields()方法能够获取一个类里面声明的所有字段,而不管这个字段是public的还是private。
            Field[] declaredFieldList=studentClass1.getDeclaredFields();
            for(Field declaredField:declaredFieldList){
                System.out.println("Declared Filed:"+declaredField);
            }
    
    //       2.获取所有公有的字段
            Field[] fieldList = studentClass1.getFields();
            for (Field field : fieldList) {
                System.out.println("-----获取公有字段-------");
                System.out.println("field: " + field);
            }
    
    //        3.获取声明的所有构造方法
            System.out.println("-----获取所有构造方法-------");
            Constructor[] declaredConstructorList=studentClass2.getDeclaredConstructors();
            for(Constructor declaredConstructor:declaredConstructorList){
                System.out.println("Constructor:"+declaredConstructor);
            }
    //        4.获取所有的public的构造方法
            System.out.println("-----获取公有构造方法-------");
            Constructor[] constructorList=studentClass3.getConstructors();
            for (Constructor constructor:constructorList) {
                System.out.println("Constructor:"+constructor);
    
    //           5.获取所有声明的函数
                System.out.println("-----获取所有非构造方法-------");
                Method[] declaredMethodList = studentClass1.getDeclaredMethods();
                for (Method declaredMethod : declaredMethodList) {
                    System.out.println("declared Method: " + declaredMethod);
                }
    //           6.获取所有公有的函数
                System.out.println("-----获取所有public的非构造方法-------");
                Method[] methodList = studentClass2.getMethods();
                for (Method method : methodList) {
                    System.out.println("method: " + method);
                }
            }
        }
    }

    测试类的运行结果如下:

    "C:Program FilesJavajdk1.8.0_221injava.exe" "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3libidea_rt.jar=50543:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_221jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_221jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_221jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_221jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_221jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_221jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_221jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_221jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_221jrelibext
    ashorn.jar;C:Program FilesJavajdk1.8.0_221jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_221jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_221jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_221jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_221jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_221jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_221jrelibjce.jar;C:Program FilesJavajdk1.8.0_221jrelibjfr.jar;C:Program FilesJavajdk1.8.0_221jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_221jrelibjsse.jar;C:Program FilesJavajdk1.8.0_221jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_221jrelibplugin.jar;C:Program FilesJavajdk1.8.0_221jrelib
    esources.jar;C:Program FilesJavajdk1.8.0_221jrelib
    t.jar;D:ideaSpaceoutproductionideaSpace" com.qa.reflection.ReflectionTest
    This is a public Constructor without arguments.
    查看Class的对象是否为同一个.
    Student Class1:class com.qa.reflection.Student
    Student Class2:class com.qa.reflection.Student
    Student Class3:class com.qa.reflection.Student
    Student Class1==Student Class2:true
    Student Class2==Student Class3:true
    Declared Filed:private java.lang.String com.qa.reflection.Student.studentName
    Declared Filed:public int com.qa.reflection.Student.studentAge
    -----获取公有字段-------
    field: public int com.qa.reflection.Student.studentAge
    -----获取所有构造方法-------
    Constructor:public com.qa.reflection.Student()
    Constructor:private com.qa.reflection.Student(java.lang.String)
    -----获取公有构造方法-------
    Constructor:public com.qa.reflection.Student()
    -----获取所有非构造方法-------
    declared Method: public void com.qa.reflection.Student.setStudentAge(int)
    declared Method: private java.lang.String com.qa.reflection.Student.show()
    -----获取所有public的非构造方法-------
    method: public void com.qa.reflection.Student.setStudentAge(int)
    method: public final void java.lang.Object.wait() throws java.lang.InterruptedException
    method: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    method: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
    method: public boolean java.lang.Object.equals(java.lang.Object)
    method: public java.lang.String java.lang.Object.toString()
    method: public native int java.lang.Object.hashCode()
    method: public final native java.lang.Class java.lang.Object.getClass()
    method: public final native void java.lang.Object.notify()
    method: public final native void java.lang.Object.notifyAll()
    
    Process finished with exit code 0

    四:Java.lang.Class里面的部分方法

    JAVA反射API

     

    五:Oracle官方文档:

    Reflcet API

    https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/package-summary.html

    Class 类

    https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html

    知乎

    https://zhuanlan.zhihu.com/p/86293659

    后记:

    今天是2020年2月12日,农历正月十九,上海,晴朗。

    由于武汉2019-nCov疫情,呆在家。

    世界卫生组织正式把这个virus命名位SARS CoV2

    SARS-CoV-2(Severe Acute Respiratory Syndrome Coronavirus 2)
    COVID-19(Corona Virus Disease 2019)

  • 相关阅读:
    JAVA基础语法练习(四)--File 及IO流
    JAVA基础语法练习(三)
    JAVA基础语法练习(二)
    JAVA基础语法练习(一)
    python 面向对象的进阶
    python面向对象基础编程
    Linux远程
    Linux系统的安装、启动及简单的命令使用
    操作系统的结构及发展历史
    操作系统简介
  • 原文地址:https://www.cnblogs.com/majestyking/p/12301182.html
Copyright © 2011-2022 走看看