【JAVA学习】七、注解,反射,字节码,类加载机制

七、注解,反射,字节码,类加载机制

一、 注解
  1. 介绍:注解是JDK5.0开始引入的新技术,注解并不是程序本身,只是对程序做出某种解释(与注释不同是可以被其他程序读取)。
  2. 内置注解:
    @Override :表示重写该方法,如果该方法不存在,则报错。
    在这里插入图片描述
    @Deprecated:遗弃废弃,被它修饰的方法,属性,类不鼓励程序员再使用,eclipse在调用被修饰的代码时会有删除线,但不影响使用。
    @SuppressWarnings :忽略警告
    在这里插入图片描述
  3. 元注解 :对注解做进一步的解释
    @Target : 描述注解的使用范围(包,类,接口,枚举, 属性,方法等)
    @Retention : 表示需要在什么级别保存该注释信息,用于描述注解的生命周期
    在这里插入图片描述
    在这里插入图片描述
二、JAVA动态性:反射机制
  1. 动态语言:程序运行时可以改变程序的结构或变量类型。(python,ruby,js)
    c,c++,java不是动态语言,但是可以通过反射机制,字节码操作等获得类似动态语言的特性。
  2. 反射机制:程序已经跑起来了,在运行时依然可以再加载一些新的类。
    Class c = Class.forName("com.as.test.User");
    对于任意一个已加载的类都可以知道这个类的所有属性的方法,对于任意一个对象,都能调用它的任意一个属性和方法。
//测试各种类型的java.lang.Class对象的获取方式
public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        String path = "com.example.annotation.bean.User";
        //方法1
        Class<?> clazz = Class.forName(path);
        //一个类被加载后,JVM会创建一个对应该类的Class对象,类的整个结构信息会放到对应的Class对象中
        //这个class对象就像一面镜子一样,通过这面镜子可以看到对应类的全部信息
        System.out.println(clazz);
        //class com.example.annotation.bean.User
        System.out.println(clazz.hashCode());
        //1555009629
        //同样一个类只会被加载一次(只有一个反射对象)
        Class<?> clazz2 = Class.forName(path);
        System.out.println(clazz.hashCode());
        //1555009629

        //方法2
        Class strClass = String.class;
        Class strClass2 = path.getClass(); //path是一个字符串
        System.out.println(strClass == strClass2);
        //true

        int[] a = new int[10];
        int[] a2 = new int[30];
        System.out.println(a.getClass().hashCode());
        System.out.println(a2.getClass().hashCode());
        //41359092
        //41359092
        int[][] a3 = new int[2][3];
        System.out.println(a3.getClass().hashCode());
        //149928006
    }
}
  1. 利用反射API获取类的信息(类名,属性,方法,构造器等)
public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        String path = "com.example.annotation.bean.User";
        Class<?> clazz = Class.forName(path);
        //获取类的名字
        System.out.println(clazz.getName());
        System.out.println(clazz.getSimpleName());
        //com.example.annotation.bean.User
        //User

        //获取类的属性
        Field[] fields = clazz.getFields();
        System.out.println(fields.length);
        //0 只能获得public修饰的属性
        Field[] fields1 = clazz.getDeclaredFields();
        System.out.println(fields1.length);
        //3 返回所有的属性
        for (Field temp : fields1){
            System.out.println(temp);
        }
        //private int com.example.annotation.bean.User.id
        //private int com.example.annotation.bean.User.age
        //private java.lang.String com.example.annotation.bean.User.uname
        Field a = clazz.getDeclaredField("uname");
        System.out.println(a);
        //private java.lang.String com.example.annotation.bean.User.uname

        //获取类的方法
        Method[] methods = clazz.getDeclaredMethods();
        Method method1 = clazz.getDeclaredMethod("getUname",null);
        Method method2 = clazz.getDeclaredMethod("setUname",String.class); //传递参数类型
        System.out.println(method1);
        System.out.println(method2);
        //public java.lang.String com.example.annotation.bean.User.getUname()
        //public void com.example.annotation.bean.User.setUname(java.lang.String)

        //获得构造器
        Constructor[] constructors = clazz.getDeclaredConstructors();
        for (Constructor temp : constructors){
            System.out.println(temp);
        }
        //public com.example.annotation.bean.User(int,int,java.lang.String)
        //public com.example.annotation.bean.User()
        Constructor constructor1 = clazz.getDeclaredConstructor(null);
        Constructor constructor2 = clazz.getDeclaredConstructor(int.class,int.class,String.class);
        System.out.println(constructor1);
        System.out.println(constructor2);
        //public com.example.annotation.bean.User()
        //public com.example.annotation.bean.User(int,int,java.lang.String)
    }
}
  1. 通过反射api动态的操作构造器,方法和属性
public class Demo01 {
    public static void main(String[] args) throws Exception{
        String path = "com.example.annotation.bean.User";
        Class<?> clazz = Class.forName(path);
        //通过反射api动态构造一些对象
        User user = (User) clazz.newInstance(); //调用了user的无参构造方法
        System.out.println(user);
        // com.example.annotation.bean.User@5caf905d
        //选择构造器
        Constructor c = clazz.getDeclaredConstructor(int.class,int.class,String.class);
        User tsc = (User) c.newInstance(1001,18,"tsc");
        System.out.println(tsc.getUname());
        //tsc

        //通过反射api调用普通方法
        User dkm = (User) clazz.newInstance();
        Method method = clazz.getDeclaredMethod("setUname", String.class);
        method.invoke(dkm,"dkm");
        System.out.println(dkm.getUname());
        //dkm

        //通过反射api操作属性
        Field f = clazz.getDeclaredField("uname");
        f.setAccessible(true); //这个属性不需要安全检查,直接访问
        f.set(dkm,"dsb");
        System.out.println(dkm.getUname());
        System.out.println(f.get(dkm));
        //dsb
        //dsb

    }
}
  1. 反射的性能问题
    尽量把setAccessible设为true,减少安全检查提高性能。
  2. 反射操作泛型
    泛型是针对编译器的,免去了强制类型转化的麻烦,一旦编译完成泛型就会擦除。(不是重点)
  3. 反射操作注解
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值