注解与反射

一. 注解

1.元注解

/**
 * Author:ckvsok
 * Date:2021/3/25
 **/

package annotation;

import java.lang.annotation.*;

@MyAnnotation
public class test01 {

}

//自定义一个注解
@Target(value = {ElementType.TYPE , ElementType.FIELD , ElementType.METHOD}) //作用目标 : 是个数组(分别是class, 字段 , 方法).....
@Retention(value = RetentionPolicy.RUNTIME) // 表示什么状态有效 .RUNTIME > CLASS > SOURCES
@Documented //注解被包含在javadoc中
@Inherited //表示子类可以继承父类
@interface MyAnnotation {
}

2.注解参数

/**
 * Author:ckvsok
 * Date:2021/3/25
 **/

package annotation;

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

@MyAnnotation2(name = "ck", age = 12, id = 1,schools = {"abc","cdv"})
public class Test02 {
    @MyAnnotation2(name = "ck")
    public void test(){
    }
    @MyAnnotation2(123) //value 赋值123, "value ="  可以省略其余按默认
    public void test2(){
    }
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
    //注解的参数, 默认值
    String name() default "";
    int age() default 0;
    int id() default -1;
    String[] schools() default {""};
    int value() default 0;  

}

二. 反射

1.获取Class对象

/**
 * Author:ckvsok
 * Date:2021/3/25
 **/

package Reflection;

public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException {

        //1、通过 类 获取 Class
        Class<Student> studentClass1 = Student.class;

        //2、根据类名 获取 Class
        Class<?> studentClass2 = Class.forName("Reflection.Student");

        //3、通过对象获取类的Class
        Student student = new Student();
        Class<? extends Student> studentClass3 = student.getClass();
    }
}

class Student{

}

2.动态创建对象

/**
 * Author:ckvsok
 * Date:2021/3/26
 **/

package Reflection;

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

//测试动态获取类的构造方法\方法\字段等
public class Test02 {
    public static void main(String[] args) throws Exception {
        //获取Class类
        Class c1 = Class.forName("Reflection.User");
        //反射获取无参构造器
        Constructor constructor = c1.getConstructor();
        System.out.println(constructor);
        //反射获取有参构造器
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class);
        System.out.println(declaredConstructor);
        //通过构造器新建对象
        User ck = (User) declaredConstructor.newInstance("Ck", 27);
        System.out.println(ck);
        //通过反射调用方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        setName.setAccessible(true);//关闭私有检测, 私有方法也可以运行
        setName.invoke(ck, "ck2");
        System.out.println(ck);
        //反射给字段赋值
        Field age = c1.getDeclaredField("age");
        age.setAccessible(true);//关闭私有检测
        age.set(ck,15);
        System.out.println(ck);


    }
}

class User{
    private String name;
    private int age;

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

    public User() {
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

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

3.反射获取泛型

/**
 * Author:ckvsok
 * Date:2021/3/27
 **/

package Reflection;

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

//测试反射获得泛型
public class Test03 {
    public static void main(String[] args) throws Exception {
        Class c1 = Test03.class;
        //获得参数泛型
        Method method1 = c1.getMethod("test01", 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);
                }
            }
        }
        System.out.println("--------------------------------------");
        //获得返回值泛型
        Method method2 = c1.getMethod("test02");
        Type genericReturnType = method2.getGenericReturnType();
        System.out.println(genericReturnType);
        if (genericReturnType instanceof  ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }

    }

    public static void test01(Map<String, User> map) {
        System.out.println("参数泛型");
    }

    public static Map<String, Student> test02() {
        System.out.println("返回值泛型");
        return null;
    }
}

4.反射操作注解

/**
 * Author:ckvsok
 * Date:2021/3/27
 **/

package Reflection;

import java.lang.annotation.*;

//反射操作注解
public class Test04 {
    public static void main(String[] args) {
        Class student2Class = Student2.class;
        //获取注解
        Annotation annotation = student2Class.getAnnotation(StudentAnnotation.class);
        System.out.println(annotation);
        //获取注解的值
        StudentAnnotation studentAnnotation = (StudentAnnotation) student2Class.getAnnotation(StudentAnnotation.class);
        System.out.println(studentAnnotation.age());
    }
}

@StudentAnnotation(id = 1, age = 12, name = "ck")
class Student2 {
    private int id;
    private int age;
    private String name;

    @Override
    public String toString() {
        return "Student2{" +
                "id=" + id +
                ", age=" + age +
                ", 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;
    }

    public String getName() {
        return name;
    }

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

    public Student2() {
    }


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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface StudentAnnotation {
    int id();

    int age();

    String name();
}

三.Java内存分析

1.堆

  • 存放new的对象和数组

  • 可以被所有的线程共享

2.栈

  • 存放基本变量类型(会包含这个基本类型的具体数值)
  • 引用对象的变量(对应堆里的地址)

3.方法区

  • 所有的class和static变量
  • 可以被所有线程共享

4.类加载过程

  • 类的加载Load
    • 将类的class文件读入内存,并为之创建一个Class对象。由类加载器完成。
  • 类的链接Link
    • 将类的二进制数据合并到 JRE 中
  • 类的初始化Initialize
    • JVM负责对类进行初始化

5.类的初始化

  • 发生类初始化
    • mian方法所在类
    • new一个对象
    • 调用类的静态成员(除了final常量)和静态方法
    • 使用反射方法对类进行反射调用
    • 初始化一个类,如果父类没有被初始化,则会先初始化他的父类
  • 不发生类初始化
    • 当访问一个静态域时,只有真正声明这个域的类才会被初始化
    • 通过数组定义类引用,不会触发此类的初始化
    • 引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池中了)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值