Java基础之注解与反射

2020-04-06  本文已影响0人  在error边缘疯狂试探

什么是注解?


元注解


自定义注解


public class Test{
  @MyAnnotation(name="cwx")
  publice void test(){}
}

@Target(value={ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
  String name();//注意,这里的name()不是方法,就是参数!
  int age() default 18;//由于这里有默认值,所以注解可以不用写这个参数,如果没有就必须要写参数!
}

动态语言 VS 静态语言


是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗的讲就是代码可以根据某些条件改变自身结构。

与动态语言相对应的,运行时结构不可变的语言,如Java、C、C++。

Java Reflection (反射)

Class c =Class.forName("java.lang.string")

Java内存分析:

类的加载与ClassLoader的理解:

什么时候回发生类初始化?

Test[ ] test = new Test[5];//Test是一个类,这里是通过数组的方式引用

3、引用常量不会触发此类的初始化(常量在链接阶段就存入了调用类的常量池中了)。

有了Class对象,能做什么?

难道没有无参的构造器就不能创建对象了吗?只要在操作的时候明确调用类中的构造器,并将参数传递进去之后,才可以实例化操作,例如:

主类:
public class Test{
  public static void main[ String[] (args) throw ClassNotFoundException, IllegalAccessException{
    Class c1 = Class.forName("com.cn.cwx.User");  
    //构造一个对象
    User user = (User) c1.newInstance();//本质是调用了类的无参构造器
    //通过构造器创建对象
    Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
    User user = (User)constructor.newInstance("cwx",001,18);
    //通过反射调用普通方法
    User user3 = (User)c1.newInstance();
    //通过反射获取一个方法,(方法名,方法参数的类类型)若方法没有参数,则写null
    Method setName = c1.getDeclaredMethod("setName",String.class);/*
    为什么要加String.class?
    因为程序需要通过该方法的参数类型去寻找方法,
    在方法中有可能会出现重载,如果不加String.class会让程序不知道找哪个方法*/

    //invoke:激活的意思
    //invoke(对象,方法的参数)若方法没有参数,则写null
    setName.invoke(user3,"cwx");
      //通过反射操作属性
      User user4 = (User)c1.Instance();
      //获得属性的名称获得属性
      Filed name = c1.getDeclaredFiled("name");
      //不能直接操作私有属性或__私有方法__,必须关闭程序的安全检测
      name.setAccessible(true);//利用`setAccessible(true)`保证安全检测关闭
      name.set("cwx2");
      //通过`user4.getName()`获得操作后的属性
}
}
User类:
public class User{
  private String name;
  private int id;
  private int age;
   有参构造;
   无参构造;
   get和set方法;

}

Tips: 如果程序里面用了很多的反射,效率很低,可以利用setAccessible(true)方法提高效率!

了解什么是ORM?

public class Test1{
  public static void main[ String[] (args) throw ClassNotFoundException, IllegalAccessException{
    
  Class c1 = Class.forName("com.cwx.student");
  //通过反射获得注解
  Annotation[] annotation = c1.getAnnotations();
  //获得注解的value的值
  Table table = (Table)c1.getAnnotation(Table.class);
    String value = table.value();

}
@Table("db_student")
class Student{
  @FieldTest(columnName="db_id",type="int",length=10)
  private int id;
  @FieldTest(columnName="db_age",type="int",length=20)
  private int age;
    get和set方法;
    有参和无参构造;
}
//自定义类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
  String value();//数据库名称
}
//自定义属性的注解
@Target(ElementType.Field)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldTest{
  String columnName();//列名
  String type();
  int length();
}

Tips: 这个例子中可以看出,其实注解是和数据库打交道的,由于可以通过反射方法获得注解的值,也就是数据库中的内容,这其实就现了类和表结构的映射关系,很多框架里面的注解都类似于这种。

上一篇下一篇

猜你喜欢

热点阅读