Enumerations, annotations, reflection and proxy mode

First, enumeration class

1, using the enumeration class

Only a limited number of object classes, determined, such as seasons: spring, summer, autumn and winter, when you need a set of constants, it is strongly recommended to use enumeration class.

Achieve enumeration class

  • jdk1.5 previously required custom enumeration class;
  • jdk1.5 new enum keyword is used to define enumeration class

If only one object enumeration, as the method for implementing a singleton pattern.

How to customize enumeration class before jdk1.5?

  • Privatization class constructor, to ensure not create object outside the class;
  • Create an instance of the enumeration class within the class declared as public static final;
  • If you have an object instance variables should be declared as pribate final, and initialize in the constructor.
package com.lwj.enumtest;


public class SeasonTest {
    public static void main(String[] args) {
        Season spring = Season.SPRING;
        System.out.println(spring);
        //Season{seasonName='春天', seasonDesc='春暖花开'}
    }
}

//自定义枚举类
class Season {
    private final String seasonName;
    private final String seasonDesc;
    private Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    public static final Season SPRING = new Season("春天", "春暖花开");
    public static final Season SUMMER = new Season("夏天", "夏日炎炎");
    public static final Season AUTUMN = new Season("秋天", "秋高气爽");
    public static final Season WINTER = new Season("冬天", "白雪皑皑");

    //获取枚举类对象的属性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

Use the keyword enum enumeration class that defines after jdk1.5

  • Use enum defined enumeration class inherits the default java.lang.Enum class, and therefore can not inherit from other classes;
  • Enum class constructor can only use the private key;
  • All enumeration class instances must be explicitly listed in the enumeration class (partition; end), examples of the listed systems will automatically add public static final modification;
  • Enum class object must be declared in the first line enumeration class;
  • jdk1.5 defined may be used in a switch Enum expression as an expression of the object classes enumerated, case statement may be used directly in the name enumeration value, defined as the need to add enumeration class.

Jdk1.5 before use custom enumeration type, the Object as a parent class, override the toString () method, and after jdk1.5 use enum keyword to define enumeration class, the parent class as java.lang.Enum , no need to override toString () method.

package com.lwj.enumtest;


public class SeasonEnumTest {
    public static void main(String[] args) {
        System.out.println(SeasonEnum.SPRING);
        //SPRING

        System.out.println(SeasonEnum.class);
        //class com.lwj.enumtest.SeasonEnum
        System.out.println(SeasonEnum.class.getSuperclass());
        //class java.lang.Enum
    }
}

enum SeasonEnum {
    SPRING("春天", "春暖花开"),
    SUMMER("夏天", "夏日炎炎"),
    AUTUMN("秋天", "秋高气爽"),
    WINTER("冬天", "白雪皑皑");

    private final String seasonName;
    private final String seasonDesc;

    private SeasonEnum(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //这次没有重写toString()方法
}

The switch may be a type parameter byte, short, int, char, Enum, StringWhich is after jdk1.5 new Enum, String is jdk1.7 new features.

  • With the back of the case must be constant;
  • Execution order is determined first case, if the match is successful, the code until break.

When the parameter is an enumeration type switch, enumerated type case: instead case enumeration class enumerated types, such as the following example:

package com.lwj.enumtest;


public enum TestEnum {
    TEST_ONE("name1", "one"),
    TEST_TWO("name2", "two"),
    TEST_THREE("name3", "three");

    private final String key;
    private final String value;
    private TestEnum(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }
}

class Test$Enum {
    public static void main(String[] args) {
        TestEnum t = TestEnum.TEST_ONE;
        switch (t) {
            case TEST_ONE:
                System.out.println(t.getKey() + ":" + t.getValue());
                break;
            case TEST_TWO:
                System.out.println(t.getKey());
                break;
            default :
                System.out.println(t);
        }
    }
}

When the parameter is a type of switch type String, such as the following example:

package com.lwj.enumtest;


public class TestString {
    public static void main(String[] args) {
        String a = "aaa";
        switch (a) {
            case "aaa":
                System.out.println("匹配aaa");
                break;
            case "bbb":
                System.out.println("匹配bbb");
                break;
            default :
                break;
        }
    }
}

Class common method Enum

  • values ​​(): Returns enum type of object array;
  • valueOf (String str): the string to a respective class object enumeration request string must be the name of an object class enumeration;
  • toString (): Returns the name of the current class object enumeration constants;
//Enum类的常用方法
System.out.println(Arrays.toString(SeasonEnum.values()));
//[SPRING, SUMMER, AUTUMN, WINTER]
System.out.println(SeasonEnum.valueOf("WINTER"));
//WINTER
System.out.println(SeasonEnum.SPRING);
//SPRING

Use enum keyword defines an enumeration class that implements the interface

  • And consistent with normal Java class, enum class can implement one or more interfaces;
  • If you need each enum value when the interface method call implementation, showing a different behavior, you can let each enumeration values ​​implement the method.
interface Info {
    void show();
}

enum SeasonEnum implements Info{
    SPRING("春天", "春暖花开") {
        @Override
        public void show() {
            System.out.println("SPRING");
        }
    },
    SUMMER("夏天", "夏日炎炎") {
        @Override
        public void show() {
            System.out.println("SUMMER");
        }
    },
    AUTUMN("秋天", "秋高气爽") {
        @Override
        public void show() {
            System.out.println("AUTUMN");
        }
    },
    WINTER("冬天", "白雪皑皑") {
        @Override
        public void show() {
            System.out.println("WINTER");
        }
    };

    private final String seasonName;
    private final String seasonDesc;

    private SeasonEnum(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //这次没有重写toString()方法
}

Second, notes

1, annotated overview

  • Jdk1.5 from the beginning, Java adds support for metadata (MetaData), which is the Annotation annotation;
  • Annotation is the special code markers that can be compiled, class loading, the runtime is read, and execute corresponding processing;
  • Annotation can be used as modifiers like, it may be used to modify the package, class, constructors, methods, member variables, parameters, local variable declaration, the information is stored in the Annotation "name = value" pairs;
  • Nature is an inherited annotation interface Annotation interface.

In JavaSE using annotations relatively simple, such as labeling methods obsolete, ignore the warnings, in JavaEE / Android, the notes occupy an important role, for example section is used to configure the application, instead of the previous version of the XML configuration JavaEE;
future development model is based annotation, notes a trend, to some extent, it can be said,= + Reflector + annotation framework design pattern

Annotation or parse a class method, there are two forms, one scanning period is compiled, one is =Runtime reflection, To discuss compile-time scanning annotation,

@Override
public String toString() {
    return "Hello Annotation";
}

@Override annotation tells the compiler that this method is an overridden method, this method does not exist if the parent class, the compiler will report an error, if I do not add @Override notes, and toString () method written in the wrong toStrring (), then execution results and expectations are biased, so the use of annotations in favor of improving the readability of the program.

2, an example of common Annotation

To increase the @ symbol in front of use Annotation, and the @Annotation used as a modifier.

Example 1: generate documentation related notes

  • @author: indicate the development of this class, with among multiple authors ,are separated;
  • @version: marked version of the class;
  • @see: reference steering; (refer to other classes)
  • @since: increased from Which version;
  • @param: Description of the process parameters; (@ param parameter name parameter type parameter description)
  • @return: Returning to the description of the method value; (@ return Return Type Description Return Value)
  • @exception: method exception thrown will be described; (@ exception exception type exception description)
  • @param and @exception can be arranged in a plurality.
package com.lwj.annotest;

import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author shawn
 * @version 1.0
 * @date 2020/3/3 12:58
 * @see Math
 */
public class JavaDocTest {
    /**
     * 程序的入口
     * @param args String[] 命名行参数
     */
    public static void main(String[] args) {
    }

    /**
     * 求圆的面积
     * @param radius double 半径值
     * @return double 圆的面积
     * @throws IOException IO异常
     */
    public static double getArea(double radius) throws IOException {
        try {
            throw new FileNotFoundException();
        } finally {
            return Math.pow(radius, 2.0) * Math.PI;
        }        
    }
}

Example Two: Check format (JDK built three basic annotation) at compile time

  • @Override: defining override inherited methods, only method for the annotation;
  • @Deprecated: represents the modified elements (classes, methods) it is obsolete, because there is usually a better choice;
  • @SuppressWarnings: suppress compiler warnings;
package com.lwj.annotest;

public class AnnotationTest {
    public static void main(String[] args) {
        @SuppressWarnings("unused")
        int a = 10;
        new AnnotationTest().print();
    }
    
    @Deprecated
    public void print() {
        System.out.println("过时的方法");
    }
    
    @Override
    public String toString() {
        return "重写的toString";
    }
}

Example Three: replace the function of the configuration file

Servlet 3.0 provides notes, no longer need to configure the Servlet, @ WebServlet ( "/ login") in web.xml.

Spring Framework @Bean ...

3, custom annotation

  • Define a new Annotation type using @interface keyword;
  • Custom annotation automatically inherit java.lang.annotation.Annotation interfaces;
  • (Method interface, the default permissions modifier for the public, so I do not consider, just consider the method name, return type and parameter)
  • Notes Only members of variables, there is no way, Annotation member variables to declare a method without parameters, the method name corresponding to the member variable name, return type corresponds to the type of member variables, which we call the configuration parameters, type only eight basic data types, String type, Class type, enum type, the Annotation type, an array of all the above types;
  • You can assign initial values ​​when member variables defined annotation, specifies the initial value of the member variables using the default keyword;
  • If only one member of parameters, it is recommended to use a parameter called value;
  • In use, the format: "parameter parameter name = value", if only one member of the parameter, and the name is value, which may be omitted "value =";
  • Member variables called annotation tags, comments, comprising a member variable called metadata annotations;
  • Notes does not support inheritance, because the notes after compilation, the compiler will automatically inherit java.lang.annotation.Annotation.

4, jdk in meta-annotation

  • jdk meta-annotation for the modification of the definition of other annotations;
  • jdk1.5 provides four standard mata-annotation types, namely: @ Retention, @ Target, @ Documented, @ Inherited;

@Retention

Annotation specify the life cycle, @ Retention RetentionPolicy contains a member variable of type, specify a value for the value member variables must use @Retention;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {

    RetentionPolicy value();
}
public enum RetentionPolicy {
    SOURCE,
    CLASS,
    RUNTIME
}

SOURCE: valid source file;

CLASS: class file is valid and does not load into the JVM, such as built-in Java annotations, @ Override, @ Deprecated, (compiler checks), the default value;

RUNTIME: runtime effective, when running a Java program, JVM will keep notes, you can obtain the annotation through reflection, as SpringMVC the @ Controller, @ RequestMapping, @ Autowired.

@Target

Annotation can be modified to specify the act on which program elements;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    
    ElementType[] value();
}
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE, //类、接口、枚举

    /** Field declaration (includes enum constants) */
    FIELD, //属性

    /** Method declaration */
    METHOD, //方法

    /** Formal parameter declaration */
    PARAMETER, //方法参数

    /** Constructor declaration */
    CONSTRUCTOR, //构造方法

    /** Local variable declaration */
    LOCAL_VARIABLE, // 局部变量

    /** Annotation type declaration */
    ANNOTATION_TYPE, //注解类型

    /** Package declaration */
    PACKAGE, //包

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Document

Annotation will be modified to specify javadoc tool to extract the document;

@Inherited

Inherited inherited meaning, but it does not mean that the annotation itself can be inherited, but that if a superclass using @Inherited annotation, so if its subclasses are not any notes application, then this subclass inherits super annotation. Use less.

Used most @Retention (RetentionPolicy.RUNTIME) and @Target ({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) these two notes.

Array using braces.

5, reflected by the information acquiring annotation

Repeat until reflection

package com.lwj.annotest;

import java.lang.annotation.*;

@MyAnnotation(value = "Byte Dancing")
public class MyAnnotationTest {
    @MyAnnotation("西安")
    private String name;

    @MyAnnotation
    public static void main(String[] args) {
        
    }
}

@MyAnnotation("哔哩哔哩")
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String value() default "MyAnnotation";
}

6, jdk8.0 notes new features

Annotations can be repeated

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    
    Class<? extends Annotation> value();
}
  • On MyAnnotation statement @Repeatable, members of the variable value is MyAnnotations.class;
  • And @Retention the same @Target @MyAnnotation and @MyAnnotations.
package com.lwj.annotest;

import java.lang.annotation.*;

@MyAnnotation(value = "JD")
@MyAnnotation(value = "Byte Dancing")
public class MyAnnotationTest {
    @MyAnnotation("西安")
    private String name;

    @MyAnnotation
    public static void main(String[] args) {

    }
}

@Repeatable(MyAnnotations.class)
@MyAnnotation("哔哩哔哩")
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String value() default "MyAnnotation";
}


@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotations {
    MyAnnotation[] value();
}

As another example, there are many roles a man, father, son, friend, and so on.

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME)
public @interface Persons {
	Person[] value();
}

@Persons annotation can be annotated to a class.

@Repeatable(Persons.class)
public @interface Person{
	String role() default "";
}

Use @Repeatable @Person annotation on annotation, annotation is @Person is repeatable.

use:

@Person(role="CEO")
@Person(role="husband")
@Person(role="father")
@Person(role="son")
public class Man {
	String name="";
}

Type of annotation

After jdk8.0, parameter values ​​for the enumeration type ElementType yuan notes @Target of more than two, TYPE_PARAMETER, TYPE_USE.

Third, reflection

1, Java reflection mechanism Overview

  • Program execution reflective mechanism allows any type of internal information acquired by the Reflection API, and can directly manipulate the internal attributes and methods of any object;
  • End loaded class, in the process of heap memory area produces a Class object type (only one of a class Class object), the object contains the complete structural information class, the object like a mirror, through this type of structure can be seen in the mirror, we called reflection.

Reflecting mainly related API

  • java.lang.Class: on behalf of a class
  • java.lang.reflect.Method: Method class representatives
  • Field representing the class: java.lang.reflect.Field
  • java.lang.reflect.Constructor: Representative class constructor
  • ...
package com.lwj.java;


public class Person {
    private String name;
    public int age;

    public Person() {
    }

    private Person(String name) {
        this.name = name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void show() {
        System.out.println("show()方法");
    }

    private String showNation(String nation) {
        System.out.println("我的国籍" + nation);
        return nation;
    }
}
package com.lwj.java;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectTest {
    public static void main(String[] args) throws Exception{
        Person p = new Person("张三", 22);
        p.age = 10;
        p.show();
        //反射之前,在Person类外部不能通过Person类的对象调用内部私有结构
        //比如name属性,私有构造器,showNation()方法
        //封装性的限制

        //反射之后
        Class<Person> clazz = Person.class;
        Constructor<Person> constructor = clazz.getConstructor(String.class, int.class);
        Person person = constructor.newInstance("张三", 22);
        Field age = clazz.getDeclaredField("age");
        age.set(person, 10);
        Method show = clazz.getDeclaredMethod("show");
        show.invoke(person);
        
        //反射的强大--->调用类的内部结构
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(person, "李四"); //访问私有属性
        System.out.println(person.getName()); //李四
        
        Constructor<Person> declaredConstructor = clazz.getDeclaredConstructor(String.class);
        declaredConstructor.setAccessible(true);
        Person person1 = declaredConstructor.newInstance("王五"); //私有构造器创建对象
        System.out.println(person1.getName()); //王五

        Method showNation = clazz.getDeclaredMethod("showNation", String.class);
        showNation.setAccessible(true);
        showNation.invoke(person1, "China"); //执行私有方法
    }
}

How to look at the conflict between reflection and encapsulation?

Not contradictory.

2, and acquires appreciated Class class instance of class Class

About class loading process:

After javac.exe program command to generate bytecode files (.class), using a command java.exe interpreted byte code file operation corresponding to a byte code file is loaded into memory, this process called load classes.

Class is loaded into memory, it referred to as runtime class, as an instance of class Class.

Gets the Class instance of four ways:

public void test() {
    //方式一:调用运行时类的属性
    Class<Person> clazz = Person.class;
    System.out.println(clazz); //class com.lwj.java.Person
    //方式二:通过运行时类的对象
    Person p = new Person();
    Class<? extends Person> clazz1 = p.getClass();
    System.out.println(clazz1); //class com.lwj.java.Person
    System.out.println(clazz == clazz1); //true
    //方式三:调用Class的静态方法
    try {
        Class<?> clazz2 = Class.forName("com.lwj.java.Person");
        System.out.println(clazz2 == clazz); //true
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    //方式四:类的加载器
    try {
        Class<?> clazz3 = ReflectTest.class.getClassLoader().loadClass("com.lwj.java.Person");
        System.out.println(clazz3 == clazz); //true
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

Class class

  • Class object objects can only be established by the system;
  • JVM loads a class there will be only one instance of Class;
  • Corresponds to a Class object is loaded into the JVM in a .class files;

What types can have a Class object?

  • class (outside of class members (members of inner classes, static inner classes), local inner classes, anonymous inner classes)
  • interface Interface
  • [] Array
  • enum Enumeration
  • annotation notes
  • Basic data types
  • void
public void test1() {
    Class<Object> c1 = Object.class;
    System.out.println(c1); //class java.lang.Object
    Class<Comparable> c2 = Comparable.class;
    System.out.println(c2); //interface java.lang.Comparable
    Class<String[]> c3 = String[].class;
    System.out.println(c3); //class [Ljava.lang.String;   L表示对象类型
    Class<int[][]> c4 = int[][].class;
    System.out.println(c4); //class [[I
    Class<ElementType> c5 = ElementType.class;
    System.out.println(c5); //class java.lang.annotation.ElementType
    Class<Override> c6 = Override.class;
    System.out.println(c6); //interface java.lang.Override
    System.out.println(c6.getSuperclass()); //null
    Class<Integer> c7 = int.class;
    System.out.println(c7); //int
    Class<Void> c8 = void.class;
    System.out.println(c8); //void
    Class<Class> c9 = Class.class;
    System.out.println(c9); //class java.lang.Class

    int[] a = new int[10];
    int[] b = new int[100];
    Class<? extends int[]> aClass = a.getClass();
    Class<? extends int[]> bClass = b.getClass();
    System.out.println(aClass == bClass); //true
    //只要数组的元素类型和维度一样,就是一个Class
}

ClassLoader loading and 3, the class understood

Here Insert Picture DescriptionHere Insert Picture Description

package com.lwj.java;


public class ClassLoadingTest {
    public static void main(String[] args) {
        System.out.println(A.m);
        //100
    }
}

class A {
    static {
        m = 300;
    }
    static int m = 100;
}
//第二步:链接结束后 m=0
//第三步:初始化后, m 的值由 <clinit> 方法执行决定
//这个 A 的类构造器 <clinit> 方法由类变量的赋值和静态代码块中的语句按照顺序合并
//产生,类似于
// <clinit>(){
// m = 300;
// m = 100;
// }

Here Insert Picture Description

package com.lwj.java;


public class ClassLoadingTest {
    public static void main(String[] args) {
        //主动引用:一定会导致类A和Father的初始化
        // A a = new A();
        // Class.forName("com.lwj.java.A");
        // System.out.println(A.m);

        //被动引用
        A[] array = new A[5];
        //不会导致类A和Father的初始化
        System.out.println(A.b);
        //只会初始化Father
        System.out.println(A.M);
        //不会导致A和Father的初始化
        
        
        //main所在的类:main方法所在的类主动初始化
        //父类被加载:调用A.b,初始化父类,而非子类
        //2
        //1:不会初始化A和Father
    }

    static {
        System.out.println("main所在的类");
    }
}

class Father {
    static int b = 2;

    static {
        System.out.println("父类被加载");
    }
}

class A extends Father{
    static {
        System.out.println("子类被加载");
        m = 300;
    }
    static int m = 100;
    static final int M = 1;
}

Here Insert Picture Description

package com.lwj.java;


public class ClassLoadingTest {
    public static void main(String[] args) throws ClassNotFoundException {
        ClassLoader classLoader = ClassLoadingTest.class.getClassLoader();
        System.out.println(classLoader);
        //获取当前自定义类ClassLoadingTest的类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);
        //获取系统类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);
        //获取系统类加载器的父类加载器,即扩展类加载器:sun.misc.Launcher$ExtClassLoader@1b6d3586
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);
        //获取扩展类加载器的父类加载器,即引导类加载器:null,不是没有,而是我们获取不到

        ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader1);
        //查看Object类是由哪个类加载器加载:null

        //关于类加载器的一个重要方法:getResourceAsStream(String str),获取类路径下指定文件的输入流
        ClassLoadingTest.class.getClassLoader().getResourceAsStream("");
    }
}

4, create objects runtime class

Here Insert Picture Description

package com.lwj.java;


import java.lang.reflect.Constructor;

public class NewInstanceTest {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("com.lwj.java.Person");
        Object obj = clazz.newInstance();
        System.out.println(obj);
        //Person{name='null', age=0} clazz.newInstance(),调用空参构造器,创建对象

        Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class);
        Object lisi = declaredConstructor.newInstance("李四", 22);
        System.out.println(lisi);
        //Person{name='李四', age=22}
    }
}

5 for a complete runtime class structure

Field、Method、Constructor、SuperClass、Interface、Annotation。

1, provide a richer Person class

interface:

package com.lwj.java1;


public interface MyInterface {
    void info();
}

annotation:

package com.lwj.java1;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "Hello";
}

father:

package com.lwj.java1;


import java.io.Serializable;

public class Creature<T> implements Serializable {
    private char gender;
    public double weight;

    private void breath() {
        System.out.println("生物呼吸");
    }

    public void eat() {
        System.out.println("生物吃东西");
    }
}

Person class:

package com.lwj.java1;

@MyAnnotation("Person")
public class Person extends Creature<String> implements Comparable<String>, MyInterface {

    private String name;
    int age;
    public int id;

    public Person() {
    }

    @MyAnnotation("constructor")
    private Person(String name) {
        this.name = name;
    }

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @MyAnnotation
    private String show(String nation) {
        System.out.println("我的国籍是" + nation);
        return nation;
    }

    public String display(String interesting) {
        return interesting;
    }

    @Override
    public int compareTo(String o) {
        return 0;
    }

    @Override
    public void info() {
        System.out.println("MyInterface接口的info方法");
    }
}

2、Field

Field [] clazz.getFields (): Get the parent class, this class is declared for the property Public

Field [] clazz.getDeclaredFields (): Get all the properties of this class declaration

package com.lwj.java2;


import com.lwj.java1.Person;

import java.lang.reflect.Field;

public class FieldTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Field[] fields = personClass.getFields();
        // 获取父类、本类中声明为public的属性
        for (Field field : fields) {
            System.out.println(field);
            //public int com.lwj.java1.Person.id
            //public double com.lwj.java1.Creature.weight
        }
        Field[] declaredFields = personClass.getDeclaredFields();
        // 获取本类声明的全部属性
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
            //private java.lang.String com.lwj.java1.Person.name
            //int com.lwj.java1.Person.age
            //public int com.lwj.java1.Person.id
        }
    }
}

Get property modifiers, type, variable name

package com.lwj.java2;


import com.lwj.java1.Person;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class FieldTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            //权限修饰符
            int modifiers = declaredField.getModifiers();
            System.out.print(Modifier.toString(modifiers) + "\t");
            //public default private
            //数据类型
            Class<?> type = declaredField.getType();
            System.out.print(type + "\t");
            //变量名
            String name = declaredField.getName();
            System.out.println(name);
        }
    }
}

3、Method

Method[] getMethods()

Method[] getDeclaredMethods()

package com.lwj.java2;


import com.lwj.java1.Person;

import java.lang.reflect.Method;

public class MethodTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Method[] methods = personClass.getMethods();
        //获取当前类及其父类中声明的所有public方法
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("-------------------");
        //获取当前类声明的所有方法
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
            //public int com.lwj.java1.Person.compareTo(java.lang.String)
            //public int com.lwj.java1.Person.compareTo(java.lang.Object)
            //public void com.lwj.java1.Person.info()
            //public java.lang.String com.lwj.java1.Person.display(java.lang.String)
            //private java.lang.String com.lwj.java1.Person.show(java.lang.String)
        }
    }
}

The method of obtaining the internal structure of the run-time class

package com.lwj.java2;


import com.lwj.java1.Person;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class MethodTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            //方法上的注解
            Annotation[] annotations = declaredMethod.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.print(annotation + "\t");
            }
            //权限修饰符
            int modifiers = declaredMethod.getModifiers();
            System.out.print(Modifier.toString(modifiers) + "\t");
            //返回值类型
            Class<?> returnType = declaredMethod.getReturnType();
            System.out.print(returnType + "\t");
            //方法名
            String name = declaredMethod.getName();
            System.out.print(name + "(");
            //形参列表
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            if (!(parameterTypes == null || parameterTypes.length == 0)) {
                for (int i = 0; i < parameterTypes.length; i++) {
                    if (i == parameterTypes.length - 1) {
                        System.out.print(parameterTypes[i].getName());
                        break;
                    }
                    System.out.print(parameterTypes[i].getName() + ",");
                }
            }
            System.out.print(")");
            //异常
            Class<?>[] exceptionTypes = declaredMethod.getExceptionTypes();
            if (!(exceptionTypes == null || exceptionTypes.length == 0)) {
                System.out.print("  throws");
                for (int j = 0; j < exceptionTypes.length; j++) {
                    if (j == exceptionTypes.length - 1) {
                        System.out.print(exceptionTypes[j]);
                        break;
                    }
                    System.out.print(exceptionTypes[j] + ",");
                }
            }
            System.out.println();
        }
    }
}

4、Constructor

package com.lwj.java2;


import com.lwj.java1.Person;

import java.lang.reflect.Constructor;

public class ConstructorTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Constructor<?>[] constructors = personClass.getConstructors();
        //获取当前运行时类中声明为public的构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
            //public com.lwj.java1.Person()
        }
        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        //获取当前运行时类中声明的所有构造器
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
            //com.lwj.java1.Person(java.lang.String,int)
            //private com.lwj.java1.Person(java.lang.String)
            //public com.lwj.java1.Person()
        }
    }
}

5, runtime class of the parent class

package com.lwj.java2;


import com.lwj.java1.Person;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class SuperClassTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Class<? super Person> superclass = personClass.getSuperclass();
        //获取运行时类的父类
        System.out.println(superclass);
        //class com.lwj.java1.Creature
        Type genericSuperclass = personClass.getGenericSuperclass();
        //获取运行时类的泛型父类
        System.out.println(genericSuperclass);
        //com.lwj.java1.Creature<java.lang.String>

        //获取泛型类型参数数组
        ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        System.out.println(actualTypeArguments[0].getTypeName());
        //java.lang.String
    }
}

6, the interface

package com.lwj.java2;


import com.lwj.java1.Person;

public class InterfaceTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Class<?>[] interfaces = personClass.getInterfaces();
        for (Class interfaceIns : interfaces) {
            System.out.println(interfaceIns);
            //interface java.lang.Comparable
            //interface com.lwj.java1.MyInterface
        }
    }
}

7, where the pack

package com.lwj.java2;


import com.lwj.java1.Person;

public class PackageTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Package aPackage = personClass.getPackage();
        System.out.println(aPackage);
        //package com.lwj.java1
    }
}

8, the class notes

package com.lwj.java2;

import com.lwj.java1.Person;

import java.lang.annotation.Annotation;


public class AnnoTest {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Annotation[] annotations = personClass.getAnnotations();
        System.out.println(annotations[0]);
        //@com.lwj.java1.MyAnnotation(value=Person)
    }
}

6, calls the runtime class specified structure

1, property

package com.lwj.java3;


import com.lwj.java1.Person;

import java.lang.reflect.Field;

public class FieldTest {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Person person = personClass.newInstance();
        Field name = personClass.getDeclaredField("name");
        //获取运行时类指定的属性
        name.setAccessible(true);
        name.set(person, "李四");
        //Field对象的set(obj, value),obj:给哪个对象赋值,value,给对象的Field属性赋哪个值
        System.out.println(name.get(person));
        //获取当前对象的Field属性值
        //李四
    }
}

2, method (most important)

package com.lwj.java3;


import com.lwj.java1.Person;

import java.lang.reflect.Method;

public class MethodTest {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Method show = personClass.getDeclaredMethod("show", String.class);
        //获取指定的方法对象 getDeclaredMethod(方法名,参数列表的Class对象)
        Person person = personClass.newInstance();
        show.setAccessible(true);
        Object china = show.invoke(person, "China");
        //调用person对象的show()方法并传递"China"参数,invoke()方法的返回值就是show()方法的返回值
        System.out.println(china);
    }
}

Static method

New static method in the Person class.

private static void showDesc() {
    System.out.println("我是一个静态方法");
}
package com.lwj.java3;


import com.lwj.java1.Person;

import java.lang.reflect.Method;

public class MethodTest {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Method showDesc = personClass.getDeclaredMethod("showDesc");
        showDesc.setAccessible(true);
        Object invoke = showDesc.invoke(Person.class);
        //我是一个静态方法
        System.out.println(invoke);
        //如果此方法没有返回值,那么invoke()方法返回null
    }
}

Similarly static properties and static method, set (Person.class, "John Doe");

3, constructor

package com.lwj.java3;


import com.lwj.java1.Person;

import java.lang.reflect.Constructor;

public class ConstructorTest {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class);
        declaredConstructor.setAccessible(true);
        Person person = declaredConstructor.newInstance("张三");
        System.out.println(person);
        //Person{name='张三', age=0, id=0}
    }
}

Examples of a representative of the class Class class is loaded into a run-time memory.

7, the reflected Application: dynamic proxy

Spring AOP framework of the principle: dynamic proxy.

Static agents, for example:

package com.lwj.java4.staticproxy;

interface ClothFactory {
    void produceCloth();
}

//代理类
class ProxyClothFactory implements ClothFactory {

    private ClothFactory clothFactory;

    public ProxyClothFactory(ClothFactory clothFactory) {
        this.clothFactory = clothFactory;
    }

    @Override
    public void produceCloth() {
        System.out.println("代理工厂做一些准备工作");
        clothFactory.produceCloth();
        System.out.println("代理工厂做一些收尾工作");
    }
}

//被代理类
class NikeClothFactory implements ClothFactory {

    @Override
    public void produceCloth() {
        System.out.println("Nike工厂生产Air Force 1");
    }
}

//代理类与被代理类在编译期就确定下来了
public class StaticProxyTest {
    public static void main(String[] args) {
        NikeClothFactory nikeClothFactory = new NikeClothFactory();
        ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nikeClothFactory);
        proxyClothFactory.produceCloth();
    }
}

Dynamic Agent For example:

package com.lwj.java4.dynamicproxy;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Human {
    String getBelief();
    void eat(String food);
}

//被代理类
class SuperMan implements Human {

    @Override
    public String getBelief() {
        return "I believe i can fly.";
    }

    @Override
    public void eat(String food) {
        System.out.println("我喜欢吃" + food);
    }
}

//动态代理类:根据被代理类,动态创建一个跟你实现一样接口的类,代理对你的执行
/*
* 要想实现动态代理,需要解决的两大问题:
* 1、如何根据加载到内存中的被代理类,动态的创建一个代理类和对象;
* 2、当通过代理类对象调用方法时,如何动态的去调用被代理类中的同名方法;*
* */

class ProxyFactory {
    //调用此方法,返回一个代理类对象
    public static Object getProxyInstance(Object obj) { //obj被代理类的对象
        MyInvocationHandler handler = new MyInvocationHandler();
        handler.setObj(obj);
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
    }
}

class MyInvocationHandler implements InvocationHandler {

    private Object obj;
    //obj代表被代理对象
    public void setObj(Object obj) {
        this.obj = obj;
    }

    //当我们通过代理类对象,调用方法getBelief/eat时,就会自动的调用如下的方法invoke()
    //将被代理类要执行的方法声明为invoke()方法中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(obj, args);
    }
}

public class ProxyTest {
    public static void main(String[] args) {
        SuperMan superMan = new SuperMan();
        Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
        System.out.println(proxyInstance.getBelief());
        proxyInstance.eat("火锅");
    }
}

Guess you like

Origin www.cnblogs.com/shawnyue-08/p/12592671.html