Java注解和反射

Java注解和反射

注解的作用

  • 注解可以被编译器识别
  • 可以添加在package,class,method,field上面,添加了额外的辅助信息,可以通过反射机制实现对元数据的访问
package com.wang.annotation;

import java.util.ArrayList;
import java.util.List;

public class learn01 extends Object{
    @Override
    public String toString() {
        return super.toString();
    }
    @Deprecated
    public static void testPrint(){
        System.out.println("Deprecated");
    }
    @SuppressWarnings("all")
    public static void testPrint2(){
        List list = new ArrayList();
    }
    public static void main(String[] args) {
        testPrint();
    }
}

元注解

  • @Target:注解的使用范围
  • @Retention:在什么级别保存该注解信息,描述注解的生命周期
  • @Documented:说明该注解将被包含在的Javadoc中
  • @Inherited:说明子类可以继承父类中的该注解
package com.wang.annotation;

import java.lang.annotation.*;

@MyAnnotation
public class learn01 {
    @MyAnnotation
    public void test(){
        
    }
}
//自定义注解
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation{}

自定义注解

package com.wang.annotation;

import java.lang.annotation.*;

public class learn03 {
    @MyAnnotation2(name = "hahaha", schools = {"kukuku"})
    public void test(){
    }
    @MyAnnotation3("HIHIHI")
    public void test2(){

    }
}
//自定义注解
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation2{
    //注解的参数:参数类型+参数名();有默认值则不需显示赋值,否则必须显示赋值
    String name() default "";
    int age() default 0;
    int id() default -1;
    String[] schools() default {"kkkk"};
}
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation3{
    //注解的参数:参数类型+参数名();有默认值则不需显示赋值,否则必须显示赋值
    String value() default "";
}

反射机制

概述

  • 动态语言:运行时可以改变其结构的语言:例如新的函数、对象,甚至代码可以被引进(Object-C,C#,JavaScript)

  • 静态语言:运行时结构不可改变(Java,C,C++)

  • Java不是动态语言,但是有一定动态性.

  • 优点:利用反射机制,编程更加灵活

  • 缺点:影响性能,使用反射基本上是解释操作

  • 通过堆内存的方法区中的Class对象(一个类只有一个),获取类的结构,属性和方法

  • 相关的API

    • java.lang.Class 代表一个类
    • java.lang.reflect.*

理解Class类并获取Class实例

package com.wang.reflection;

import java.util.Objects;

public class learn0 extends Object{
    public static void main(String[] args) throws ClassNotFoundException {
        //通过反射获取类的Class对象
        Class name1 = Class.forName("com.wang.reflection.User");
        System.out.println(name1);
        Class name2 = Class.forName("com.wang.reflection.User");
        Class name3 = Class.forName("com.wang.reflection.User");
        Class name4 = Class.forName("com.wang.reflection.User");
        System.out.println(name2.hashCode());//hashCode相同,一个类在内存只有一个Class对象
        System.out.println(name3.hashCode());//类被加载后,整个结构都会被封装在Class对象中
        System.out.println(name4.hashCode());
    }
}
//实体类
class User{
    private String name;
    private int age;
    private int id;

    public User() {
    }

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

    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 int getId() {
        return id;
    }

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

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

//    @Override
//    public boolean equals(Object o) {
//        if (this == o) return true;
//        if (o == null || getClass() != o.getClass()) return false;
//        User user = (User) o;
//        return age == user.age && id == user.id && Objects.equals(name, user.name);
//    }
//
//    @Override
//    public int hashCode() {
//        return Objects.hash(name, age, id);
//    }
}
package com.wang.reflection;

import java.lang.annotation.Target;

public class learn1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println(person.name);
        //三种方法获取Class对象
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());
        Class c2 = Class.forName("com.wang.reflection.Student");
        System.out.println(c2.hashCode());
        Class c3 = Student.class;
        System.out.println(c3.hashCode());
        Class c4 = Integer.TYPE;//基本包装类型有一个TYPE属性
        System.out.println(c4);
        //获取父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);

    }
}
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 = "student";
    }
}
class Teacher extends Person{
    public Teacher(){
        this.name = "teacher";
    }
}

反射的性能

package com.wang.reflection;

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

public class learn02 {
    public static void main(String[] args) throws Exception {
        t1();
        t2();
        t3();
    }

    private static void t3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Student student = new Student();
        Class s = student.getClass();
        Method method = s.getDeclaredMethod("getId",null);
        method.setAccessible(true);
        long startTime = System.currentTimeMillis();
        for(int i = 0 ; i < 2100000000; ++i){
            method.invoke(student,null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("关闭检测反射方法"+(endTime-startTime)+"ms");
    }

    private static void t2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Student student = new Student();
        Class s = student.getClass();
        Method method = s.getDeclaredMethod("getId",null);
        long startTime = System.currentTimeMillis();
        for(int i = 0 ; i < 2100000000; ++i){
            method.invoke(student,null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射方法"+(endTime-startTime)+"ms");
    }

    private static void t1() {
        Student student = new Student();
        long startTime = System.currentTimeMillis();
        for(int i = 0 ; i < 2100000000; ++i){
            student.getId();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通方法"+(endTime-startTime)+"ms");
    }
}

posted @ 2021-11-15 16:06  ddl战士  阅读(34)  评论(0)    收藏  举报