注解和反射

注解

image.png

内置注解

image.png

元注解

image.png
package annotation;

import java.lang.annotation.*;

//测试元注解
public class test1 {
    public void test(){

    }
}
//定义一个注解
//Target表示我们的注解可以用在哪些地方
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//表示我们的注解在什么地方有用
@Retention(value = RetentionPolicy.RUNTIME)
//Documented 表示是否将我们的注解生成在JAVAdoc中
@Documented
//Inhertied子类可以继承父类的注解
@Inherited
@interface MyAnnotation{

}

自定义注解

注解可以显示赋值,如果没有默认值,我们就必须给注解赋值

  • @MyAnnotation(name="shy”)

注解的参数:参数类型+参数名();

  • int age() default 0;
  • 如果默认值为负一,表示不存在

反射

动态语言

  • Object-C,C#,JavaScript,PHP,Python.

静态语言

  • Java,C,C++

优点:可实现动态对象的创建和编译,体现出很大的灵活性
缺点:对性能有影响

  • Class c1=Class.forName("com.kuang.reflection.User")
  • 一个类在内存中只有一个Class对象

Class类

image.png

Class类的常用方法

image.png
package reflection;

import java.lang.reflect.Constructor;

public class test1 {
   public static void main(String[] args) throws ClassNotFoundException {
       Person person=new Student();
       System.out.println("这个人是"+person.name);
       //方式1:通过对象获得
       Class c1 = person.getClass();
       System.out.println(c1.hashCode());
       //方式2:通过forname获得
       Class c2 = Class.forName("reflection.Student");
       System.out.println(c2.hashCode());
       //方式3:通过类名.class获得
       Class c3=Student.class;
       System.out.println(c3.hashCode());
       //方式4:基本内置类型包装都有一个TYPE属性
       Class c4 = Integer.TYPE;
       System.out.println(c4.hashCode());
       //获得父类类型
       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="学生";
   }
}
class Teacher extends Person{
   public Teacher(){
       this.name="老师";
   }
}

拥有class对象的类型

image.png

类的加载

  • alt+insert(可以生成构造器)
package reflection;

public class test2 {
    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=100;

    public A() {
        System.out.println("A类无参构造初始化");
    }
}
//m=100

类的初始化

类的主动引用(一定会发生类的初始化)

  • 当虚拟机启动,先初始化main方法所在的类
  • new一个类的对象
  • 调用类的静态成员(除了final常量)和静态方法
  • 使用iava.lang.reflect包的方法对类进行反射调用
  • 当初始化一个类,如果其父类没有被初始化,则先会初始化它的父类

类的被动引用(不会触发类的初始化)

  • 当访问一个静态域时,只有真正声明这个域的类才会被初始化。如:当通过子类引用父类的静态变量,不会导致子类初始化
  • 通过数组定义类引用,不会触发此类的初始化
  • 引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池中了)
package reflection;

public class test3 {
    static {
        System.out.println("Main被加载");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        //1.主动引用
        Son son = new Son();
        //反射也会产生主动引用
        Class.forName("reflection.Son");
    }
}
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;
}

类加载器

  • 作用是把类装载进内存


    image.png

创建运行时类的对象

获取类的名字

  • c1.getName(获得包名加类名)
  • c1.getSimpleName(获得类名)

获得类的属性

  • c1.getFields(只能找到public属性)
  • c1.getDeclareFields()找到全部属性

获得类的方法

  • c1.getMethods();
  • c1.getDeclaredMethods();

获得制定构造器

  • c1.getConstructors();

动态创建对象执行方法

package reflection;

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

public class test4 {
    public static <User> void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //获取Class对象
        Class c1 = Class.forName("reflection.User");
        //构造一个对象
         User user = (User) c1.newInstance();//本质是调用了类的无参构造器
        //通过构造器创建对象
        Constructor  constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        User user2 =(User) constructor.newInstance("shy", 001, 18);
        //通过反射构造普通方法
        User user3 = (User) c1.newInstance();
        Method setName = c1.getDeclaredMethod("setName", String.class);
        setName.invoke(user3,"shy");//invoke激活
        System.out.println(user3.getClass());
    }
}

setAccessible

  • 启动和禁用访问安全检查开关

反射操作泛型

image.png

获取注解信息

package reflection;

import javax.swing.text.html.parser.TagElement;
import java.lang.annotation.*;

public class test5 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Class.forName("reflection.Student2");
        //通过反射获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation:annotations){
            System.out.println(annotation);
        }
        //获得注解Value的值
        Tableshy tableshy = (Tableshy)c1.getAnnotation(Tableshy.class);
        String value = tableshy.value();
        System.out.println(value);
        //获得类的指定注解
        
    }

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

    public Student2(int id,int age,String name) {
        this.id = id;
        this.age= age;
        this.name=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;
    }
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tableshy{
    String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldshy{
    String columnName();
    String type();
    int length();
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容