Basic knowledge of Java Reflection (ii)

Source: Internet
Author: User

1. Understanding reflection in Java 1.1 What is the reflection of Java

Java reflection is a mechanism that allows us to get the class's internal information such as functions, properties, parent classes, interfaces, and so on at run time. Reflection also allows us to instantiate an object at run time, invoke a method, get the value of a variable by calling the Get/set method, even if the method or property is private and can be invoked in the form of reflection, this ability to "see Through the class" is called introspection, which is especially important in framework development. In some cases, the class we want to use is determined at runtime, and we cannot use it at compile time, so we can only use a class that exists at runtime in the form of reflection (which conforms to a particular specification, such as JDBC), which is a much more reflective scenario.
Another common scenario is that when compiling, we do not know the internal information of the class, we must get runtime to get the concrete information of the class. An ORM framework, for example, can fetch individual properties in a class at run time, and then get its property names and values in a reflection form and deposit them into the database. This is also one of the classic application scenarios for reflection comparison.

1.2 Class

So since reflection is the operation of class information, what is class?

When we have finished writing a Java project, all Java files are compiled into a. class file that hosts the original information of this type of parent class, interface, constructor, method, property, and so on, which are ClassLoader when the program runs. Loaded into the virtual machine. When a class is loaded, the Java virtual machine automatically generates a class object in memory. The creation of objects through new means is actually created through these classes, but the process is not transparent to us.
In the following sections we will show you some of the common APIs for reflection, from the point of view of code to understand reflection.

2. Reflection class and construction object 2.1 Get Class object

Before you want to check the information of a class, you first need to get the class object of the classes. All types in Java include the base type, even if the array has an object of the class class associated with it. If you know the name of a class at compile time, you can use the following method to get a class object.

Class<?> myObjectClass = MyObject.class;

If you've got an object, but you want to get the object's Class object, you can get it in the following way:

Student me = new Student("mr.simple");Class<?> clazz = me.getClass();

If you don't get the target type at compile time, but you know its full classpath, you can get the class object in the following form:

Class<?> myObjectClass = Class.forName("com.simple.User");

When using the Class.forName () method, you must provide the full name of a class, which includes the name of the package in which the class resides. For example, if the User class is in the Com.simple package, then his complete classpath is com.simple.User.
If the corresponding class is not found under the compilation path (CLASSPATH) when the Class.forName () method is called, the ClassNotFoundException will be thrown.

Interface description

// 加载指定的 Class 对象,参数 1 为要加载的类的完整路径,例如"com.simple.Student". ( 常用方式 )public static Class<?> forName (String className)// 加载指定的 Class 对象,参数 1 为要加载的类的完整路径,例如"com.simple.Student";// 参数 2 为是否要初始化该 Class 对象,参数 3 为指定加载该类的 ClassLoader.public static Class<?> forName (String className, boolean shouldInitialize, ClassLoader classLoader)
2.2 Constructing objects of the target type through the Class object

Once you get the Class object, you can do whatever you like! When you make good use of it, it is the weapon of God, and when you shifty it becomes a demon. But getting the class object is only the first step, and we need to construct the object of that type through the class object before performing those powerful behaviors before releasing its energy through the object. We know that in Java to construct an object, you have to pass the constructor of that class, so the reflection is the same. But they do make a difference, by constructing the object by reflection, we first get the class's Constructor (constructor) object, and then we create the object of the target class through Constructor. or directly on the code.

    private static void classForName() {        try {            // 获取 Class 对象            Class<?> clz = Class.forName("org.java.advance.reflect.Student");            // 通过 Class 对象获取 Constructor,Student 的构造函数有一个字符串参数            // 因此这里需要传递参数的类型 ( Student 类见后面的代码 )            Constructor<?> constructor = clz.getConstructor(String.class);            // 通过 Constructor 来创建 Student 对象            Object obj = constructor.newInstance("mr.simple");            System.out.println(" obj :  " + obj.toString());        } catch (Exception e) {            e.printStackTrace();        }    }

With the code above, we can build the object at run time with the full class name.

Get constructor interface

// 获取一个公有的构造函数,参数为可变参数,如果构造函数有参数,那么需要将参数的类型传递给 getConstructor 方法public Constructor<T> getConstructor (Class...<?> parameterTypes)// 获取目标类所有的公有构造函数public Constructor[]<?> getConstructors ()

Notice that when you get to Constructor, Method, Field through reflection, the accessible flag of this object is set to true before the reflection call to increase the reflection speed. A value of TRUE indicates that the reflected object should cancel the Java language access check when it is used. A value of false indicates that the reflected object should implement a Java language access check. For example:

   Constructor<?> constructor = clz.getConstructor(String.class);   // 设置 Constructor 的 Accessible   constructor.setAccessible(true);   // 设置 Methohd 的 Accessible   Method learnMethod = Student.class.getMethod("learn", String.class);   learnMethod.setAccessible(true);

Since the Student and related classes are used later, we'll give them the code here first.
Person.java

public class Person {    String mName;    public Person(String aName) {        mName = aName;    }    private void sayHello(String friendName) {        System.out.println(mName + " say hello to " + friendName);    }    protected void showMyName() {        System.out.println("My name is " + mName);    }    public void breathe() {        System.out.println(" take breathe ");    }}

Student.java

public class Student extends Person implements Examination {    // 年级    int mGrade;    public Student(String aName) {        super(aName);    }    public Student(int grade, String aName) {        super(aName);        mGrade = grade;    }    private void learn(String course) {        System.out.println(mName + " learn " + course);    }    public void takeAnExamination() {        System.out.println(" takeAnExamination ");    }    public String toString() {        return " Student :  " + mName;    }

Breathe.java

// 呼吸接口public interface Breathe {    public void breathe();}

Examination.java

// 考试接口public interface Examination {    public void takeAnExamination();}
3 Reflection Gets the function in the class 3.1 gets the method defined in the current class

The

To get all the methods defined in the current class can pass the Getdeclaredmethods function in class, which gets all the methods of public, default, protected, private in the current class. The Getdeclaredmethod (String name, class...<?> parametertypes) is the one that gets the specified method. The code example is as follows:

  private static void Showdeclaredmethods () {Student Student = new Student ("Mr.simple");        Method[] methods = Student.getclass (). Getdeclaredmethods ();        For (method Method:methods) {System.out.println ("declared Method Name:" + method.getname ());            try {Method Learnmethod = Student.getclass (). Getdeclaredmethod ("Learn", String.class);            Gets the list of parameter types for the method class<?>[] paramclasses = Learnmethod.getparametertypes ();            for (class<?> class1:paramclasses) {System.out.println ("The parameter type of the Learn method:" + class1.getname ()); }//Is the private function, if the property is private, you can also use this method to Judge System.out.println (Learnmethod.getname () + "            is private "+ modifier.isprivate (Learnmethod.getmodifiers ()));        Learnmethod.invoke (student, "Java--->");        } catch (Exception e) {e.printstacktrace (); }    }
3.2 Gets the public method defined in the current class, parent class

To get the current class and all public methods in the parent class can pass the GetMethods function in class, while GetMethod is getting a specified method. The code examples are as follows:

    private static void showMethods() {        Student student = new Student("mr.simple");        // 获取所有方法        Method[] methods = student.getClass().getMethods();        for (Method method : methods) {            System.out.println("method name : " + method.getName());        }        try {            // 通过 getMethod 只能获取公有方法,如果获取私有方法则会抛出异常,比如这里就会抛异常            Method learnMethod = student.getClass().getMethod("learn", String.class);            // 是否是 private 函数,属性是否是 private 也可以使用这种方式判断            System.out.println(learnMethod.getName() + " is private " + Modifier.isPrivate(learnMethod.getModifiers()));            // 调用 learn 函数            learnMethod.invoke(student, "java");        } catch (Exception e) {            e.printStackTrace();        }    }

Interface description

// 获取 Class 对象中指定函数名和参数的函数,参数一为函数名,参数 2 为参数类型列表public Method getDeclaredMethod (String name, Class...<?> parameterTypes)// 获取该 Class 对象中的所有函数( 不包含从父类继承的函数 )public Method[] getDeclaredMethods ()// 获取指定的 Class 对象中的**公有**函数,参数一为函数名,参数 2 为参数类型列表public Method getMethod (String name, Class...<?> parameterTypes)// 获取该 Class 对象中的所有**公有**函数 ( 包含从父类和接口类集成下来的函数 )public Method[] getMethods ()

It is important to note that Getdeclaredmethod and getdeclaredmethods contain functions of private, protected, default, public, and that the functions obtained by these two functions are simply defined in themselves, Functions that are integrated from the parent class cannot be obtained. GetMethod and GetMethods contain only the public function, which is also available in the parent class.

4 Reflection gets the properties in the class

The Get property and the Get method in Chapter 3 are very similar, just changed from GetMethod function to GetField, from Getdeclaredmethod to Getdeclaredfield.

4.1 Getting the properties defined in the current class

To get all the properties defined in the current class, you can pass the Getdeclaredfields function in class, which gets all the properties of public, default, protected, private in the current class. The Getdeclaredfield, in other case, gets a specified property. The code examples are as follows:

    private static void showDeclaredFields() {        Student student = new Student("mr.simple");        // 获取当前类和父类的所有公有属性        Field[] publicFields = student.getClass().getDeclaredFields();        for (Field field : publicFields) {            System.out.println("declared field name : " + field.getName());        }        try {            // 获取当前类和父类的某个公有属性            Field gradeField = student.getClass().getDeclaredField("mGrade");            // 获取属性值            System.out.println(" my grade is : " + gradeField.getInt(student));            // 设置属性值            gradeField.set(student, 10);            System.out.println(" my grade is : " + gradeField.getInt(student));        } catch (Exception e) {            e.printStackTrace();        }    }
4.2 Gets the public property defined in the current class, parent class

To get the current class and all public properties in the parent class can go through the GetFields function in class, and GetField gets a specified property. The code examples are as follows:

    private static void showFields() {        Student student = new Student("mr.simple");        // 获取当前类和父类的所有公有属性        Field[] publicFields = student.getClass().getFields();        for (Field field : publicFields) {            System.out.println("field name : " + field.getName());        }        try {            // 获取当前类和父类的某个公有属性            Field ageField = student.getClass().getField("mAge");            System.out.println(" age is : " + ageField.getInt(student));        } catch (Exception e) {            e.printStackTrace();        }    }

Interface description

// 获取 Class 对象中指定属性名的属性,参数一为属性名public Method getDeclaredField (String name)// 获取该 Class 对象中的所有属性( 不包含从父类继承的属性 )public Method[] getDeclaredFields ()// 获取指定的 Class 对象中的**公有**属性,参数一为属性名public Method getField (String name)// 获取该 Class 对象中的所有**公有**属性 ( 包含从父类和接口类集成下来的公有属性 )public Method[] getFields ()

It is important to note that Getdeclaredfield and Getdeclaredfields contain the properties of private, protected, default, public, and that the two functions get only the properties defined in themselves. Attributes that are integrated from the parent class cannot be obtained. GetField and GetFields contain only the public property, which is also available in the parent class.

5 Reflection Get Parent class with interface 5.1 get parent class

Gets the parent class of the class object.

    Student student = new Student("mr.simple");    Class<?> superClass = student.getClass().getSuperclass();    while (superClass != null) {        System.out.println("Student‘s super class is : " + superClass.getName());        // 再获取父类的上一层父类,直到最后的 Object 类,Object 的父类为 null        superClass = superClass.getSuperclass();    }
5.2 Getting the interface

Gets the interface implemented in the Class object.

    private static void showInterfaces() {        Student student = new Student("mr.simple");        Class<?>[] interfaceses = student.getClass().getInterfaces();        for (Class<?> class1 : interfaceses) {            System.out.println("Student‘s interface is : " + class1.getName());        }    }
6 Getting annotation information

In framework development, the combined use of annotation and reflection is the most common form. For information on annotations, refer to the Java annotations of the public technology point Annotation, when defining annotations we specify the types that the annotations can function by @target, as shown in the following example:

    @Target({            ElementType.METHOD, ElementType.FIELD, ElementType.TYPE    })    @Retention(RetentionPolicy.RUNTIME)    static @interface Test {    }

The @target of the above note indicates that the annotation can only be used on functions, as well as type, Field, PARAMETER and other types, and can refer to the references given above. Through the reflection API we are also able to get a Class object to get types, properties, functions and other related objects, through the Getannotation interface of these objects to obtain the corresponding annotation information. First we need to add annotations to the target object, such as:

@Test(tag = "Student class Test Annoatation")public class Student extends Person implements Examination {    // 年级    @Test(tag = "mGrade Test Annotation ")    int mGrade;    // ......}

The annotation information is then obtained by the relevant annotation function, as follows:

    private static void getAnnotationInfos() {        Student student = new Student("mr.simple");        Test classTest = student.getClass().getAnnotation(Test.class);        System.out.println("class Annotatation tag = " + classTest.tag());        Field field = null;        try {            field = student.getClass().getDeclaredField("mGrade");            Test testAnnotation = field.getAnnotation(Test.class);            System.out.println("属性的 Test 注解 tag : " + testAnnotation.tag());        } catch (Exception e) {            e.printStackTrace();        }    }

The output is: >

class Annotatation tag = Student class Test Annoatation属性的 Test 注解 tag : mGrade Test Annotation

Interface description

// 获取指定类型的注解public <A extends Annotation> A getAnnotation(Class<A> annotationClass) ;// 获取 Class 对象中的所有注解public Annotation[] getAnnotations() ;
Zatan

As an important feature of the Java language, reflection plays a very important role in development. Many development frameworks are based on reflection to achieve the operation of the target object, and the reflective mate annotation is the mainstream choice of the design development framework, such as activeandroid, so a deep understanding of the role of reflection and use for future development and learning will certainly be of great benefit.

Basic knowledge of Java Reflection (ii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.