反射与注解学习笔记

反射和注解

代码:https://gitee.com/longzhiquan/reflection

注解 Annotation

1. 内置注解

  • @Override: 重写超类中的另一个方法
  • @Deprecated: 不鼓励程序员用的方法
  • @SuppressWarnings: 抑制编译时的警告信息
    • @SuppressWarnings("all")
    • @SuppressWarnings("unchecked")

2. 元注解

解释其他注解的注解

  • @Target: 描述注解的适用范围
  • @Retention: 描述注解的生命周期
  • @Document: 说明注解被包含在javadoc中
  • @Inherited: 说明子类可以继承父类中的该注解
import java.lang.annotation.*;

//测试元注解
public class Test01 {

    public void test(){

    }
}

//在方法上有效,在类上有效
@Target(value = {ElementType.METHOD, ElementType.TYPE})
//在运行时有效
//runtime>class>source
@Retention(value = RetentionPolicy.RUNTIME)
//将注解生成在javadoc中
@Documented
//子类可以继承父类注解
@Inherited
@interface MyAnnotation{

}

3. 自定义注解

import java.lang.annotation.*;

public class Test02 {

    //如果没有默认值,我们就必须给注解赋值
    @MyAnnotation2(name="hou", schoolds = {"大学"})
    public void test(){

    }
    
    //如果只有一个参数用value命名,可以省略value
    @MyAnnotation3("hou")
    public void test1(){
        
    }
}

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
    //注解参数:参数类型+参数名()默认值是空
    String name() default "";
    int age() default 0;
    int id() default -1; //如果默认值是-1,代表不存在
    String[] schoolds();
}

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
    String value();
}

反射 reflection

1. 概述

反射机制允许程序在执行期间借助于Rflection API取得任何类的内部消息,并能直接操纵任意对象的内部属性及方法。

Class c = Class.forName("java.lang.String")

加载完类之后,在堆内存的方法区中就产生一个Class类型的对象

正常方式:

  1. 引入需要的包
  2. 通过new实例化
  3. 去的实例化对象

反射方式:

  1. 实例化对象
  2. getClass()方法
  3. 得到完成的”包类“名称

2. 反射对象

package hou;

public class Test03 {

    public static void main(String[] args) throws ClassNotFoundException {
        //通过反射获得class对象
        Class c1 = Class.forName("hou.User");
        System.out.println(c1);

        //hashcode一样
        Class c2 = Class.forName("hou.User");
        Class c3 = Class.forName("hou.User");
        Class c4 = Class.forName("hou.User");

    }
}

class User{

    private String name;
    private int age;

    public User() {
    }

    public User(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;
    }
}

三种方法:

package hou;

public class Test04 {
    public static void main(String[] args) throws ClassNotFoundException {
        People people = new Student();
        System.out.println(people);

        //通过对象获得
        Class c1 = people.getClass();

        //forname获得
        Class c2 = Class.forName("hou.People");

        //通过类名.class获得
        Class<Student> c3 = Student.class;
        //hashcode一样

        //获得父类
        Class c5 = c1.getSuperclass();
        System.out.println(c5);
    }
}

class People{
    private String name;

    public People() {
    }

    public People(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Student extends People{
    public Student() {
        super("学生");
    }
}

class Teacher extends People{
    public Teacher() {
        super("Teacher");
    }
}

所有类型对象

public class Test05 {
    public static void main(String[] args) {
        Class c1 = Object.class;
        Class c2 = Comparable.class;
        Class c3 = String[].class;
        Class c4 = int[][].class;
        Class c5 = Override.class;  //注解
        Class c6 = ElementType.class;  //枚举
        Class c7 = Integer.class;  //基本数据类型
        Class c8 = void.class;  //void
        Class c9 = Class.class; //Class
    }
}

3. 类加载理解

public class Test06 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);
    }
}

class A{
    static{
        System.out.println("A静态代码块");
        m = 300;
    }

    static int m = 200;

    public A(){
        System.out.println("A无参");
    }
}

output

A静态代码块
A无参
200

4. 类的初始化

package hou;

public class Test07 {
    static {
        System.out.println("Main");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        //主动引用
//        Son son = new Son();

        //反射也会产生主动引用
//        Class.forName("hou.Son");
//        Main
//        father
//        Son
        //不会产生引用
//        System.out.println(Son.f);
//        Main
//        father
//        0

//        Son[] sons = new Son[5];
//        Main

        System.out.println(Son.n);
//        Main
//        1
    }
}

class Father{
    static int f = 0;
    static {
        System.out.println("father");
    }
}

class Son extends Father{
    static{
        System.out.println("Son");
        m = 300;
    }

    static int m = 200;
    static final int n = 1;
}

5. 类的加载器

public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取系统类加载器
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        System.out.println(classLoader);

        //获取系统加载器的父类-->扩展加载器
        ClassLoader classLoader1 = classLoader.getParent();
        System.out.println(classLoader1);

        //获取扩展加载器的父类-->根加载器
        ClassLoader classLoader2 = classLoader1.getParent();
        System.out.println(classLoader2);

        //系统类加载器
        System.out.println(Class.forName("hou.Test08").getClassLoader());
        //根加载器
        System.out.println(Class.forName("java.lang.Object").getClassLoader());
    }
}

6. 获取运行时的结构

package hou;

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

public class Test09 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("hou.User");

        System.out.println(c1.getName());  //包名+类名
        System.out.println(c1.getSimpleName());  //类名

        //获得所有属性
        Field[] fields = c1.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        //获得public方法
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        //获得指令属性
        Field name = c1.getDeclaredField("name");
        System.out.println(name);

        //获得指定方法
        Method getname = c1.getMethod("getName", null);
        Method setname = c1.getMethod("setName", String.class);
        System.out.println(getname);
        System.out.println(setname);

        //获得指定的构造器
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        //获得指令构造器
        Constructor constructor = c1.getConstructor(String.class, int.class);
        System.out.println(constructor);
    }
}

7. 动态创建对象

package hou;

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

public class Test10 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class c1 = Class.forName("hou.User");

        User use = (User) c1.newInstance();
        System.out.println(use);

        Constructor constructor = c1.getConstructor(String.class, int.class);
        User user2 = (User) constructor.newInstance("hou", 18);
        System.out.println(user2);

        //通过反射调用方法
        User user3 = (User) c1.newInstance();
        Method setname = c1.getMethod("setName", String.class);
        setname.invoke(user3, "dong");
        System.out.println(user3.getName());

        //获取反射操作属性
        User user4 = (User) c1.newInstance();
        Field field = c1.getDeclaredField("age");
        field.setAccessible(true);
        field.set(user4, 100);
        System.out.println(user4.getAge());
    }
}

8. 反射操作泛型

通过反射获取泛型

package hou;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class Test11 {

    public void test1(Map<String, User> map){
        System.out.println("test1");
    }

    public List<User> test2(){
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method1 = Test11.class.getMethod("test1", Map.class);
        Type[] genericParameterTypes = method1.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println(genericParameterType);
            if(genericParameterType instanceof ParameterizedType){
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }

        Method method2 = Test11.class.getMethod("test2", null);
        Type genericReturnType = method2.getGenericReturnType();
        if(genericReturnType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }
    }
}

9. 反射操作注解

package hou;

import java.lang.annotation.*;
import java.lang.reflect.Field;

//反射操作注解
public class Test12 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("hou.Student2");
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获得注解的值
        Table annotation = (Table) c1.getAnnotation(Table.class);
        String value = annotation.value();
        System.out.println(value);

        Field name = c1.getDeclaredField("name");
        MyField mf = name.getAnnotation(MyField.class);
        System.out.println(mf.columnName());
        System.out.println(mf.length());
        System.out.println(mf.type());
    }
}

@Table("hou")
class Student2{
    @MyField(columnName = "dbname", type = "String", length = 10)
    private String name;
    @MyField(columnName = "dbid", type = "int", length = 2)
    private int id;
    @MyField(columnName = "dbage", type = "int", length = 2)
    private int age;

    public Student2() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Student2{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
}

//类名注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
    String value();
}

//属性注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyField{
    String columnName();
    String type();
    int length();
}
posted on 2020-04-26 13:09  longzhi  阅读(231)  评论(0)    收藏  举报