【JavaSE总结】注解和反射

一、注解

1、元注解

元注解用来解释其他注解

  • @Target 描述注解的范围
  • @Retention 注释信息的级别,注解的生命周期
  • @Documented 该注释将被包含在javadoc中
  • @Inherited 子类可以继承父类中该注解

2、内置注解

一些已经写好了的注解

  • @Override 重写
  • @Deprecated 不推荐程序员使用,但是可以使用或者存在更好的方式
  • @SuppressWarnings(“all”) 用来抑制编译时所有的警告信息(参数有7种可以填,自行百度)

3、自定义注解

(此处填多个元注解,如:@Target({ElementType.TYPE,ElementType.METHOD})@interface MyAnnotation{
	函数体(如:String name() default "";//类型 参数名() default 默认值int类型参数默认值如果为-1,则表示不存在)
}

4、反射读取注解

类对象.getAnnotations() 可以返回一个Annotation[],包括这个对象的所有注解(是对象的注解,不包括它属性的注解)。可以加参数,参数为某个注解名.class,返回一个Annotation对象,可以调用这个对象的某个字段获取这个注解的某个参数的值。如:

注解名 annotation = (注解名)c.getAnnotation(注解名.class);
String value = annotation.value();

c为用了这个注解的类的某个实例化对象

二、反射

反射是Java成为准动态语言的关键,它使Java动态获取属性成为可能。但是这也会使程序的运行变慢。
普通方式执行速度>关闭安全检测执行速度>反射方式执行速度

1、Class类

获得类的n种方式

这里自定义了一个Person类用来列举Class的4种获取方式

//先实例化一个person对象
Person person = new Student();

//方式一:通过对象获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());

//方式二:forname获得
Class c2 = Class.forName("zxt.Reflection.Student");
System.out.println(c2.hashCode());

//方式三:通过 类名.class获得
Class c3 = Student.class;
System.out.println(c3.hashCode());

//方法四:基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4.hashCode());
所有类型的Class
Class c1 = Object.class;//对象
Class c2 = Comparable.class;//接口
Class c3 = String[].class;//一维数组
Class c4 = int[][].class;//二维数组
Class c5 = Override.class;//注解
Class c6 = ElementType.class;//枚举类型
Class c7 = Integer.class;//基本数据类型
Class c8 = void.class;//空类型
Class c9 = Class.class;//Class本身

打印这9个对象:

class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.annotation.ElementType
class java.lang.Integer
void
class java.lang.Class

2、类加载机制

我们写的.java文件会被编译器编译成.class文件,当某个类被需要后,jvm就会加载对应的.class文件,并创建对象加载到jvm的内存中。
并不是代码写出来就都会被加载,举个例子理解一下:

public class Test {
    static {
        System.out.println("main类被加载");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        System.out.println(Son.b);//子类调用父类的变量,不会加载子类
        Son[] array = new Son[5];//数组只被声明,不会加载类
        System.out.println(Son.M);//常量在常量池里,不会加载类
    }
}

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;
}

输出结果是:

main类被加载
父类被加载
2
1

双亲委派机制

当在上层加载器中已存在与自己写的同名的类,会使用已存在的类。比如:自己写了一个Java.lang.String,无法正常使用,会使用根加载器里的。

获取类加载器

Class类型的对象的getClassLoader()方法,可以知道这个对象是谁加载的。
如:

Class aClass = Class.forName("com.Reflection.Test01");
System.out.println(aClass.getClassLoader());

打印:

sun.misc.Launcher$AppClassLoader@18b4aac2

3、重要方法

这些比较特殊,单独拎出来

调用对象方法说明
类对象或构造器newInstance()实例化对象
方法对象invoke(对象,…args)激活某个方法,先传入调用这个方法的对象,再传入调用这个方法要传的参数列表
属性对象set(对象,字段)修改某个对象的某个属性,先传要修改属性的对象,再传修改后的值
方法说明
getName()获得包名 + 类名
getSimpleName()获得类名
getFields()获得公有属性
getDeclaredFields()获得所有定义过的属性(包括私有)
getDeclaredField(String name)根据属性名获取属性
getMethods()获得本类及父类的所有公有方法
getDeclaredMethods()获得本类的所有公有方法
getMethod(String name,…parameterTypes)根据方法名获取指定方法(第二个参数是获取的方法的参数类型)
getDeclaredConstructor()获取某个Class对象的构造器,参数列表为构造器参数的Class
setAccessible(true)关闭某个对象的安全检测,使私有属性可以被操作
getGenericParameterTypes()获取泛型信息

上一篇 GUI图形界面化编程

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新手且笨蛋37

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值