JavaSE学习心得——注解与反射

什么是注解

在这里插入图片描述

内置注解

在这里插入图片描述

元注解

在这里插入图片描述

package annotation;

import java.lang.annotation.*;

//什么是注解
@MyAnnotation
public class test1 {

    public void test() {

    }

}

//定义一个注解
//Target 表示我们的注解可以用在哪些地方
@Target(value = {ElementType.METHOD, ElementType.TYPE})//METHOD是方法,TYPE是类

//Retention,表示我们的注解在什么地方还有效
//runtime>class>source
@Retention(value = RetentionPolicy.RUNTIME)

//Documented表示是否将我们的注解生成在Javadoc中
@Documented

//Inherited 子类可以继承父类的注解
@Inherited
@interface MyAnnotation {

}

自定义注解

在这里插入图片描述

package annotation;

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

//自定义注解
public class Test2 {
    @MyAnnotation2(age = 3)
    public static void main(String[] args) {

    }
    
    @MyAnnotation3("aaa")
    private void test(){
        
    }
}

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
    String value();//只有value可以省略,直接写
}

反射

在这里插入图片描述
在这里插入图片描述

获得反射对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package reflection;

//什么叫反射
public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException{
        //通过反射获取类的Class对象
        Class c1 = Class.forName("reflection.User");
        System.out.println(c1);

        Class c2 = Class.forName("reflection.User");
        Class c3 = Class.forName("reflection.User");
        Class c4 = Class.forName("reflection.User");

        //一个类在内存中只有一个Class对象
        //一个类被加载后,类的整个结构都会背封装在Class对象中
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());

    }
}

//实体类pojo
class User{
    private String name;
    private int id;
    private int age;


    public User() {
    }

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

得到Class类几种方式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package reflection;

//测试class类的创建方式有哪些
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person=new Student();
        System.out.println("这个人是:"+person.name);
        //方式一:通过对象获得
        Class  c1 = person.getClass();
        System.out.println(c1.hashCode());

        //方法2:forName获得
        Class<?> c2 = Class.forName("reflection.Student");
        System.out.println(c2.hashCode());

        //方法3
        Class<Student> c3 = Student.class;
        System.out.println(c3.hashCode());

        //方法4:基本内置类的包装类都有一个Type属性
        Class c4=Integer.TYPE;
        System.out.println(c4.hashCode());

        //获得父类的类型(Student的父类是Person)
        Class c5 = c1.getSuperclass();
        System.out.println(c5.hashCode());
        Class c6 = Class.forName("reflection.Person");
        System.out.println(c6.hashCode());

    }
}

class Person{
   public String name;

    public Person() {

    }

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

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

class Student extends Person{
    public Student() {
        this.name="学生";
    }
}

class Teacher extends Person{
    public Teacher() {
        this.name="老师";
    }
}

在这里插入图片描述

所有类型的Class对象

package reflection;

import java.lang.annotation.ElementType;

//所有类型的Class
public class Test03 {
    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


        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

        //只要元素类型与维度一样,就是同一个Class
        int [] a=new int[10];
        int [] b=new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());
    }
}

类加载内存分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package reflection;

public class Test04 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.m);
        /**
         1.加载到内存,会产生一个类对应的Class对象
         2.链接,链接结束后m=0
         3.初始化
         <clinit>(){
         System.out.println("A类静态代码块初始化");
         m = 300;
         m = 100;

         }
        */
    }
}
class A{
    static {
        System.out.println("A类静态代码块初始化");
        m=300;
    }

    /**
     m = 300;
     m = 100;
     **/
    static int m=100;

    public A() {
        System.out.println("A的无参构造器初始化");
    }
}

在这里插入图片描述
在这里插入图片描述

分析类初始化

在这里插入图片描述

package reflection;

//测试类什么时候会初始化
public class Test05 {
    static {
        System.out.println("main类被加载");
    }
    public static void main(String[] args) throws ClassNotFoundException {
        //1.主动引用
        //Son son = new Son();

        //反射也会产生主动引用
        //Class.forName("reflection.Son");

        //不会产生类的引用的方法
        //System.out.println(Son.b);

        //数组只有main方法被加载
        //Son[] array=new Son[5];

        System.out.println(Son.M);



    }
}

class Father{
    static int b=2;

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

class Son extends Father{

    static {
        System.out.println("子类被加载");
        m=300;
    }

    static int m=100;
    static final int M=1;
}

类加载器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package reflection;


public class Test06 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取系统的类的加载器-->用户级别
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

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

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

        //测试当前类是哪个加载器加载的
        ClassLoader loader = Class.forName("reflection.Test06").getClassLoader();
        System.out.println(loader);

        //测试JDK内置的类是谁加载的-->根加载器
        ClassLoader aClass = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(aClass);

        //如何获得系统加载器可以加载的路径
        System.out.println(System.getProperty("java.class.path"));

        /**
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;
         C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;
         E:\IDEA\MyStudy\MyJava\out\production\MyJava;
         E:\IDEA\IntelliJ IDEA 2020.1\lib\idea_rt.jar
         */


    }
}

在这里插入图片描述

获取运行时类的完整结构

在这里插入图片描述

package reflection;


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

//获取类的信息
public class Test07 {
    public static void main(String[] args) throws Exception {
        Class c1 = Class.forName("reflection.User");

        //获得类的名字
        System.out.println(c1.getName());//获得包名 + 类名
        System.out.println(c1.getSimpleName());//获得类名

        //获得类的属性
        Field[] fields = c1.getFields();//只能找到public属性
        fields = c1.getDeclaredFields();//得到全部的属性

        for (Field field:fields) {
            System.out.println(field);
        }

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

        System.out.println("================================================================");
        //获得类的方法
        Method[] methods = c1.getMethods();//获得本类及其父类的全部public方法
        for (Method method : methods) {
            System.out.println("getMethods:"+method);
        }
        System.out.println("------------------------------------------------------------------");
        Method[] declaredMethods = c1.getDeclaredMethods();//获得本类的所有方法
        for (Method method : declaredMethods) {
            System.out.println("getDeclaredMethods:"+method);
        }

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

        System.out.println("================================================================");
        //获取构造器
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("getConstructors"+constructor);
        }
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor constructor : declaredConstructors) {
            System.out.println("getDeclaredConstructors"+constructor);
        }

        System.out.println("================================================================");
        //获取指定的构造器
        Constructor constructor = c1.getConstructor(String.class, int.class, int.class);
        System.out.println("指定的构造器:"+constructor);


    }
}

"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:E:\IDEA\IntelliJ IDEA 2020.1\lib\idea_rt.jar=63628:E:\IDEA\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;E:\IDEA\MyStudy\MyJava\out\production\MyJava" reflection.Test07
reflection.User
User
private java.lang.String reflection.User.name
private int reflection.User.id
private int reflection.User.age
================================================================
private java.lang.String reflection.User.name
================================================================
getMethods:public java.lang.String reflection.User.getName()
getMethods:public int reflection.User.getId()
getMethods:public void reflection.User.setName(java.lang.String)
getMethods:public int reflection.User.getAge()
getMethods:public void reflection.User.setAge(int)
getMethods:public void reflection.User.setId(int)
getMethods:public final void java.lang.Object.wait() throws java.lang.InterruptedException
getMethods:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
getMethods:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
getMethods:public boolean java.lang.Object.equals(java.lang.Object)
getMethods:public java.lang.String java.lang.Object.toString()
getMethods:public native int java.lang.Object.hashCode()
getMethods:public final native java.lang.Class java.lang.Object.getClass()
getMethods:public final native void java.lang.Object.notify()
getMethods:public final native void java.lang.Object.notifyAll()
------------------------------------------------------------------
getDeclaredMethods:public java.lang.String reflection.User.getName()
getDeclaredMethods:public int reflection.User.getId()
getDeclaredMethods:public void reflection.User.setName(java.lang.String)
getDeclaredMethods:public int reflection.User.getAge()
getDeclaredMethods:public void reflection.User.setAge(int)
getDeclaredMethods:public void reflection.User.setId(int)
================================================================
public java.lang.String reflection.User.getName()
public void reflection.User.setName(java.lang.String)
================================================================
getConstructorspublic reflection.User()
getConstructorspublic reflection.User(java.lang.String,int,int)
getDeclaredConstructorspublic reflection.User()
getDeclaredConstructorspublic reflection.User(java.lang.String,int,int)
================================================================
指定的构造器:public reflection.User(java.lang.String,int,int)

Process finished with exit code 0

动态创建对象执行方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

性能对比分析

反射用的比较多的话建议使用setAccessible(true);来关闭检测

package reflection;

import java.lang.reflect.Method;

//分析性能问题
public class Test09 {

    //普通方法调用
    public static void test01(){
        User user=new User();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10_0000_0000; i++) {
            user.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通方法执行10亿次"+(endTime-startTime)+"ms");
    }

    //反射方法调用
    public static void test02() throws Exception {
        Class c1 = Class.forName("reflection.User");
        User user = (User)c1.newInstance();
        Method getName = c1.getMethod("getName",null);

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10_0000_0000; i++) {
            getName.invoke(user,null);

        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射方法执行10亿次"+(endTime-startTime)+"ms");
    }

    //反射方法调用 关闭检测
    public static void test03() throws Exception {
        Class<?> c1 = Class.forName("reflection.User");
        User user = (User)c1.newInstance();
        Method getName = c1.getMethod("getName",null);
        getName.setAccessible(true);

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10_0000_0000; i++) {
            getName.invoke(user,null);

        }
        long endTime = System.currentTimeMillis();
        System.out.println("关闭检测方法执行10亿次"+(endTime-startTime)+"ms");
    }

    public static void main(String[] args) throws Exception {
        test01();
        test02();
        test03();
    }
}

在这里插入图片描述

获取泛型信息

在这里插入图片描述

package reflection;

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 Test10 {

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

    public Map<String,User> test02(){
        System.out.println("test02");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method test01 = Test10.class.getMethod("test01", Map.class, List.class);
        Type[] genericParameterTypes = test01.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 test02 = Test10.class.getMethod("test02", null);
        Type genericReturnType = test02.getGenericReturnType();
        if (genericReturnType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println("%"+actualTypeArgument);
            }
        }


    }
}

在这里插入图片描述

获取注解信息

在这里插入图片描述

package reflection;

import java.lang.annotation.*;

//练习反射操作注解
public class Test11 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("reflection.Student2");

        //通过反射获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        //获得注解的value的值
        Table table =(Table) c1.getAnnotation(Table.class);
        String value = table.value();
        System.out.println(value);

        //获得类指定的注解
        java.lang.reflect.Field field= c1.getDeclaredField("id");
        Field annotation=(Field) field.getAnnotation(Field.class);
        System.out.println(annotation.columnName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());

    }

}

@Table("db_student")
class Student2{
    @Field(columnName = "db_id",type = "int",length = 10)
    private int id;
    @Field(columnName = "db_age",type = "int",length = 10)
    private int age;
    @Field(columnName = "db_name",type = "varchar",length = 3)
    private String name;

    public Student2() {
    }

    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;
    }

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

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

//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field{
    String columnName();
    String type();
    int length();

}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

至南岸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值