【java基础】关于注解和反射

这里注解和反射的学习仅仅是一点基础的梳理,仅限于为使用javaweb打基础,更深入的内容还是去实践或者查阅文档吧

1.java注解

用来修饰对象,方法类之类的东西

1.常见的注解

//junit注解 @Test @After @Before
//jdk自带三个注解 Override强制认为是重写 Deprecate表示这个被注解对象过期
//SupportWarning("")用来屏蔽编译器报错

2.自定义注解以及赋值

public @interface MyAnnotation {
    //看起来很很像是方法,但是这东西叫配置参数,需要在调用注解的时候进行赋值
    String[] value1();
    int value2();
}


调用的时候是这样的
@MyAnnotation(value1 = {"第一个参数","而且这是个数组"},value2 = 1)

 3.四大元注解

//这四个是元注解,要写在注解文件里面的,平时用不到
@Retention(RetentionPolicy.CLASS)//这东西放在注解文件里面,这个注解的控制生命周期
@Target(value = {TYPE,FIELD,METHOD})//指定这个注解能注解什么东西
@Documented //代表被注解的类会提取成文档
@Inherited //代表被继承的类如果使用了Inherited修饰的注解,子类也自动带有该注解
public @interface MyAnnotation {
    //看起来很很像是方法,但是这东西叫配置参数,需要在调用注解的时候进行赋值
    String[] value1();
    int value2();
}

2.Java反射

1.Java反射机制:

正常的类加载流程是通过new实例化一个对象,然后调取对象内部的方法。而反射机制就是和正常的反过来,我们直接根据一些方法得到Class类的对象,然后根据这个Class对象去获取这个类的一些信息(个人的粗浅理解)

2.神魔是class对象?

class类对象,并不是我们寻常定义的那些,这类对象不是我们能够定义的,而是类加载器生成的。通俗来讲,class类对象是修饰类的类(天知道这句话啥意思),本质上来说class类对应的是一个一个的class文件。

每当我们定义了一个类,编译器会将其编译为.class文件,里面包含了这个类的信息

同时jvm还会对应这个class文件生成一个class对象,这个class对象就像一个窗口,能对应访问class文件和里面的信息,这个过程也可以称之为反射

(内存分析以后再说)

3.获取class对象的方法如下

//Class对象对应的是JVM中的class文件,包含了一个类所有的信息
        //集中获取class的方法
        //1.第一种,通过类的名字获取
        Class a1= Class.forName("Anno_refl.user");//(注意这里要的是类的属性)

        ///2.第二种,直接用类的静态属性class
        Class a2=user.class;

        //3.第三种,根据类的实例对象获取
        Class a3=u.getClass();

        //4.第四种,根据基本数据类型用TYPE获取
        Class a4= Integer.TYPE;//(这个也有class属性)




        //获取一个class对象后,我们就可以得到这类的全部信息,比如这个类的父类是什么
        Class a_father=a1.getSuperclass();//例如这里直接获得了object类

其中2.3是来源于object,也就是说所有类都会继承这个方法,也就是通用的

4.获取到class类对象后,我们可以从中获取我们需要的信息:

这里注意一个问题,比如Method,Field这些类和class类很像,都是对应某个方法,某个属性,但是这些无法统筹在class类里面

        //获取类的简单名字
        String SimpleName=a1.getSimpleName();

        //获取类的完整名字(包括包名字)
        String name=a1.getName();

        //获取类的指定属性(public)
        Field field=a1.getField("num");

        //获取类的指定属性(全部)
        Field field2=a1.getDeclaredField("num");

        //获取全部的public属性
        Field[] arrFields=a1.getFields();

        //获取全部的属性
        Field[] arrFields2=a1.getDeclaredFields();

        //获取指定的方法(需要指明方法名字和参数类型(参数类型也要class类))
        Method method=a1.getMethod("getNum");
        Method method2=a1.getMethod("setNum",Integer.TYPE);

        //获取全部的public方法
        Method[] arrMethod=a1.getMethods();

        //获取全部的方法
        Method[] arrMethod2=a1.getDeclaredMethods();

5.也可以反过来利用class类对象创建实例化的对象

主要有两个方法:第一个newIntance,这个默认调用无参构造器生成对象

第二个方法是先创建构造器类,再根据这个构造器类对象进行实例化

//利用反射创建对象
        user u1= (user) a1.newInstance();//这个方法有更好的替代,而且记得要强转一下

        Constructor constructor=a1.getDeclaredConstructor(Integer.TYPE);//调用某个有参构造器
        user u2= (user) constructor.newInstance(12);

6.根据获取到的一些信息进行调用:

举例子:对get到的Method进行调用的方法为invoke(obj,para)

u为一个实例化的对象
method是u对应的class类里面获取到的Method类对象
12,是这个Method对象对应的方法所需要的参数
method.invoke(u,12)

获取属性和设置属性的方法分别为set,get

//在实例化对象u中获取,field对应的属性
field.get(u)
//在实例化对象u中获取,field对应的属性,并将其修改为12
field.set(u,12)

其他还有获取注解等方法,大同小异了

你可能感兴趣的:(java预备知识,java,jvm,开发语言)