注解 与 反射

注解Annotation

在这里插入图片描述

内置注解

@override:定义重写声明

@Deprecated:表示不鼓励使用

@SuppressWarnings:抑制警告信息

使用需要参数 参数已经定义好了 选择使用即可

1.@SuppressWarnings(“all”)

2.@SuppressWarnings(“unchecked”)

3.@SuppressWarnings(value={“unchecked”,“deprecation”})

package First;

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

public class Demo01  extends  Object{
    //@Override 重写的注解
    @Override
    public String toString() {
        return "Demo01{}";
    }
    //@Deprecated 不推荐程序员使用 但是可以使用 一般有更好的方法
    @Deprecated
    public  static void test(){
        System.out.println("Deprecated");
    }
    @SuppressWarnings("all") //下方未使用的警告不再提示
    public  static void test02(){
        List list = new ArrayList();
    }

    public static void main(String[] args) {
        test();
    }
}
12345678910111213141516171819202122232425

元注解 meta-annotation

在这里插入图片描述

自定义注解 @interface

package First;

import java.lang.annotation.*;

//@MyAnnotation 定义注解目标为方法 故不可以使用
public class Test02 {


        @MyAnnotation//定义注解目标为方法 故可以使用
        public void test(){
    }
}

//@Target 表示我们的注解可以用在那些地方 值为ElementType
@Target(value = ElementType.METHOD)

//@Retention 表示我们的注解可以用在哪些地方
//runtime运行时>class>sourcejava
@Retention(value = RetentionPolicy.RUNTIME)
//@Documented 表示是否我们的注解生成在JAVAdoc中
@Documented
@Inherited //表示子类可以继承注解

@interface MyAnnotation{}
123456789101112131415161718192021222324

在这里插入图片描述

package First;

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

public class Test03 {
    @MyAnnotation03("当场注解")
    @MyAnnotation02(age = 10,name = "alin")//参数顺序可以调换 必许带参数名
    public void test03(){
        
    }
    
}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation02{
    //参数定义 参数类型 参数名()
    String name() default "";//default 进行默认赋值
    int age() default 0;
    int id()  default -1;//表示不存在
    String[] students() default {"青岛大学","南京邮电大学" };
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface  MyAnnotation03{
    String value();//一个参数时 最好命名为value 命名为value时 在使用此注解时可以不加value
}

反射Reflection

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

在这里插入图片描述

package Reflection;

public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //通过反射获取类的Class类型
        Class  c1 = Class.forName("Reflection.User");
        Class  c2 = Class.forName("Reflection.User");
        Class  c3 = Class.forName("Reflection.User");
        //一个类只有一个Class对象 故c1 c2 c3 hashcode相同
        //一个类被加载之后 类的整个结构都会被封装在Class对象中
        System.out.println(c1.hashCode());
        System.out.println(c1.hashCode());
        System.out.println(c1.hashCode());
    }
}

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

    public User() {
    }

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

在这里插入图片描述

Class类

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

获得class的方法

package Reflection;



public class Demo02 {
    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
        Class c2 = Student.class;
        System.out.println(c2.hashCode());
        //通过forname获得class
        Class c3 = Class.forName("Reflection.Student");
        System.out.println(c3.hashCode());
        //通过内置函数的包装类获得class
        Class c4 = Integer.TYPE;
        System.out.println(c4);
        //获得父类的class
        Class c5 = c1.getSuperclass();
        System.out.println(c5);

    }
}


class Person{
    public String name;

    public Person() {
    }

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

有Class对象

在这里插入图片描述

package Reflection;

import java.net.InterfaceAddress;
import java.util.Enumeration;

//拥有class对象的类型
public class Demo03 {
    public static void main(String[] args) {
        Class c1 = Object.class;
        Class c2 = Comparable.class;
        Class c3 = String[].class;
        Class c4 = int[][].class;
        Class c5 = Enumeration.class;
        Class c6 = Integer.class;
        Class c7 = Override.class;
        Class c8 = Void.class;
        Class c9 = void.class;
        Class c10 = 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 );
        System.out.println(c10);

        //当类型和维数相同时只有一个class对象
        int[] a = new int[10];
        int[] b = new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());

    }
}

输出:
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.util.Enumeration
class java.lang.Integer
interface java.lang.Override
class java.lang.Void
void
class java.lang.Class

加载类class

package Reflection;

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

    }
}
/*
    1.加载到内存,会产生一个类对应Class对象在堆区
    2.链接,在栈中产生 main m=0;
    3.初始化
    <clinit>{
    System.out.println("A类静态代码块初始化");
        m=300;
        m=100;  静态 按顺序执行的 若把 int m =100 ;放上面 则为300;
        }

 */

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

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


输出:
A类静态代码块初始化
A类的无参构造器
100

类的初始化
在这里插入图片描述

package Reflection;

public class Demo05 {
    static {
        System.out.println("Main类被调用了");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        //1.创建对象 若父类没初始化 先初始化父类
        //Son son = new Son();
        /*
        Main类被调用了
        父类被加载
        子类被加载了
        100
         */
        //2.通过反射
        //Class c1 = Class.forName("Reflection.Son");//Main类被调用  父类被加载  子类被加载了
        //3.调用静态
        //System.out.println(Son.m);//Main类被调用了 父类被加载 子类被加载了 200

        //被动引用
        //子类引用父类静态变量
        //System.out.println(Son.b);//Main类被调用了 父类被加载 100
        //数组定义类引用,不触发初始化
        //Son[] a1 = new Son[5]; Main类被调用了
        //引用常量,不触发初始化
        //System.out.println(Son.M);      Main类被调用了 1

    }
}
class Father{
    static {
        System.out.println("父类被加载");
        //int b=10;
    }
    static int b =100;
}
class Son extends Father{
    static {
        System.out.println("子类被加载了");
        m=300;
    }
    static int m=200;
    static final int M=1;
}

类加载器

在这里插入图片描述

双亲委派机制: 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。

img

动态创建对象

invoke setAccessible

在这里插入图片描述

package Reflection;

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

public class Demo08 {
    public static void main(String[] args) throws Exception {
        Class c1 = Class.forName("Reflection.User");
        //反射得到对象
        //User user = (User) c1.newInstance();//调用无参构造器 new一个对象  高版本此方法已过时 使用c1.getDeclaredConstructor().newInstance()
        //System.out.println(user);
        //使用构造器
        //Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        //User user1=(User)constructor.newInstance("小明",18,001);
        //System.out.println(user1);
        //反射调用普通方法
        User user= (User) c1.newInstance();
        //通过反射获取一个方法
        Method setName = c1.getMethod("setName",String.class);
        //invoke 激活 (对象,"方法的值")
        setName.invoke(user,"ck");
        System.out.println(user.getName());
        //通过反射操作属性
        System.out.println("==========");
        User user1=(User)c1.newInstance();
        Field name = c1.getDeclaredField("name");
        name.setAccessible(true);//关闭安全检测 对私有属性可以操作
        name.set(user1,"小小");
        System.out.println(user1.getName());
        
    }
}
ck
==========
小小
123456789101112131415161718192021222324252627282930313233343536

性能检测

package Reflection;

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

public class Demo09 {
    //普通调用
    public static void test01(){
        User user = new User();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }
        long endTime =System.currentTimeMillis();
        System.out.println("普通调用10亿次耗费"+(endTime-startTime)+"ms");
    }
    //反射调用
    public static   void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }
        long endTime =System.currentTimeMillis();
        System.out.println("反射调用10亿次耗费"+(endTime-startTime)+"ms");
    }
    //关闭安全检测
    public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }
        long endTime =System.currentTimeMillis();
        System.out.println("关闭安全检测后反射调用10亿次耗费"+(endTime-startTime)+"ms");
    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        test01();
        test02();
        test03();
    }


}
普通调用10亿次耗费4ms
反射调用10亿次耗费2063ms
关闭安全检测后反射调用10亿次耗费1265ms

可以看出 反射的方式调用 耗时较久

通过反射获得注解

package Reflection;

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

public class Demo11 {
    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);
        }
        //获得注解的值
        Typekang typekang =(Typekang) c1.getAnnotation(Typekang.class);
        String value =typekang.value();
        System.out.println(value);
        //获得指定注解的值
        Field field = c1.getDeclaredField("name");
        Fieldkang fieldkang =  field.getAnnotation(Fieldkang.class);
        System.out.println(fieldkang.columname());
        System.out.println(fieldkang.type());
        System.out.println(fieldkang.length());
    }

}

@Typekang("db_Student")
class Student2{
    @Fieldkang(columname = "db_name",type = "varchar",length = 10)
    private String name;
    @Fieldkang(columname = "db_age",type = "int",length = 10)
    private int age;
    @Fieldkang(columname = "db_id",type = "int",length = 10)
    private  int id;

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

    public Student2() {
    }
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface  Typekang{
      String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldkang{
    String columname();
    String type();
    int length();
}



@Reflection.Typekang(value=db_Student)
db_Student
db_name
varchar
10
posted @ 2021-02-24 16:27  夏小皮  阅读(70)  评论(0编辑  收藏  举报