20220810 第五组 罗大禹 学习笔记

20220810 第五小组 罗大禹 学习笔记

Java 注解及反射

学习重点

1.注解
2.反射

学习内容

Java 注解及反射

注解:

注解:Annotation,又叫做Java标注,是JDK5引入的一种机制。

Java中类,方法,变量,参数,包都可以被标注

元注解:专门给注解加的注解

可以使用@interface声明注解

我们发现注解中可以有方法,
  1. 定义方法的格式:String name();

  2. 可以有默认值,也可以没有,如果没有默认值在使用的时候必须填写对应的值,如果需要有默认值,使用default指定默认值。

  3. 如果想在使用的时候不指定具体的名字,可以将方法名写为value,若有多个参数,则需要写名字

如果不学习反射,注解没啥用!!!

在java的整个的注解体系中,有3个非常重要的主干类,
  1. Annotation 接口,定义一些常用的方法

  2. ElementType 枚举类型

    它用来指定注解的类型。通俗的来讲,我的注解要用在哪里???

  3. RetentionPolicy 枚举类型

    它用来指定注解的策略 通俗的来讲 不同类型的策略指定的注解的作用域不同

    1. SOURCE,注解仅存在于编译器处理期间,编译期处理完之后,这个注解就没用了
    2. CLASS,注解在.class文件中依然有效。
    3. RUNTIME,编译期是不起作用的,只有在运行期才由JVM读取。

Java自带的注解,共有10个。4个注解在java.lang.annotation

其余6个注解在java.lang

作用在代码上的注解
  1. @Override:检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中没有该方法,会报错

  2. @Deprecated:标记它标记的方法表示为过时的方法。

  3. @SuppressWarnings:使编辑器去忽略警告

    传入参数作用:

    1. all:忽略所有警告
    2. boxing:忽略装箱、拆箱警告
    3. rawtypes:使用生成时没有指定数据类型
    4. unchecked:忽略没有进行类型检查操作的警告
    5. unused:忽略没有使用的警告
  4. @SafeVarargs:JDK7开始支持。忽略任何使用参数为泛型变量的方法或构造器产生的警告

  5. @FunctionalInterface:JDK8开始支持。标识一个接口为函数式接口

  6. @Repeatable:JDK8开始支持。标识某个注解可以在同一个声明上使用多次

元注解:
  1. @Retention:标识这个注解作用域

  2. @Documented:标记这个注解是否包含在用户文档中

  3. @Target:这个注解可以修饰哪些信息

  4. @Inherited:如果在声明注解时,这个注解用上了@Inherited注解,那么其子类也会继承这个注解

反射

反射的概述

​ JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个

方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。要想解剖一个类,必须先要获取到该类的字节

码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

什么是反射

​ 反射就是把java类中的各种成分映射成一个个的Java对象例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可

以对一个类进行解剖,把个个组成部分映射成一个个对象。(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)

通过反射可访问的主要描述信息

获取类对象的三种方法:

        // 1.直接使用类名.class
       	Class<Dog> clazz = Dog.class;
        // 2.使用全类名
        Class aClass = Class.forName("com.jsoft.morning.Dog");
        // 3.使用对象
        Dog dog = new Dog();
        Class aClass1 = dog.getClass();

反射的举例说明:

Dog类

接下来的举例需要用到此类

@Bean
public class Dog {

    public String type;
    private String name;
    private String color;

    public Dog() {

    }

    private Dog(String name){
        this.name = name;
    }

    public Dog(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @MyAnnotation(value = 20,age=10)
    public void show(String str) {
        System.out.println("show方法..." + str);
    }

    public String info() {

        return "info方法";
    }

    private void fun() {
        System.out.println("私有的fun方法...");
    }
}
对类的操作
import java.lang.reflect.InvocationTargetException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.sql.SQLOutput;
import java.util.Arrays;
import java.net.URL;


public class Ch02 {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        
        // 获取类对象
		Class<Dog> clazz = Dog.class;	
        // 对类对象操作
        // 获取类的名字
        System.out.println(clazz.getName());
        // 获取类的加载器
        ClassLoader classLoader = clazz.getClassLoader();
        System.out.println(classLoader);
        // 获取资源
        URL resource = clazz.getResource("");
        // 获取父类
        System.out.println(clazz.getSuperclass());
        // 判断一个类是不是接口,数组
        System.out.println(clazz.isArray());
        System.out.println(clazz.isInterface());
        // 重点,使用class类对象实例化一个对象
        @SuppressWarnings("all")
        Dog dog = clazz.newInstance();
        // 获取类的构造器
        // 通过构造器实例化对象
        clazz.getDeclaredConstructor().newInstance();

        // 获得该类的指定的注解
        Bean annotation = clazz.getAnnotation(Bean.class);
        // 获得该类的所有注解
        Annotation[] annotations = clazz.getAnnotations();
        Method show = clazz.getDeclaredMethod("show", String.class);
        
    }
}
对成员变量的操作
import java.lang.reflect.Field;
import java.util.Arrays;

public class Ch03 {

    public static void main(String[] args) throws NoSuchFieldException {
        // 
        Class<Dog> clazz = Dog.class;
        // 只能获取到指定的public的属性
        Field type = clazz.getField("type");
        System.out.println(type);
        // 获取全部的public属性
        Field[] fields = clazz.getFields();
        System.out.println(Arrays.toString(fields));

        // 可以获取到指定的private属性
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);
        System.out.println(name.getType());
        // 获取全部的属性
        Field[] declaredFields = clazz.getDeclaredFields();
        System.out.println(Arrays.toString(declaredFields));

    }
}
获取对象的属性
import java.lang.reflect.Field;

public class Ch05 {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Dog dog = new Dog();
        dog.setType("萨摩耶");
        Class clazz = Dog.class;
        // 获取type属性
        Field type = clazz.getDeclaredField("type");
        // 想要获取哪一个对象的type
        String str = (String) type.get(dog);
        System.out.println(str);
        
        // 对dog的type属性进行更改
        // 注意,若更改的属性为private,在修改之前需要暴力注入
        type.set(dog,"拉布拉多");	
        System.out.println(dog.getType());
		
        // color为私有化属性
        Field color = clazz.getDeclaredField("color");
        // 暴力注入
        color.setAccessible(true);
        // 对dog的color属性进行更改
        color.set(dog,"black");
        System.out.println(dog.getColor());

    }
}
对方法的操作
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Ch06 {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException {

        Class dogClass = Class.forName("com.jsoft.morning.Dog");
        Dog dog = (Dog) dogClass.newInstance();

        Class<Dog> clazz = Dog.class;
        // 获取形参为String,方法名为show的公共方法
        Method show = clazz.getMethod("show", String.class);
        
        // 此方法的形参数量
        System.out.println(show.getParameterCount());
        
        // 获取此方法的方法名
        System.out.println(show.getName());
        Class<?>[] parameterTypes = show.getParameterTypes();
        System.out.println(Arrays.toString(parameterTypes));
        
        // 执行方法,使用反射调用方法,调用dog的show方法,传入"hello"
        show.invoke(dog,"hello");
        
		// 获得所有公开的方法,包括继承来的方法
        Method[] methods = clazz.getMethods();
        
		// 获得指定的方法,可获得私有化的
        Method fun = clazz.getDeclaredMethod("fun");
        fun.setAccessible(true);
        fun.invoke(dog);
        
        // 获得所有的方法,可获得所有访问权限的方法,无法获得继承而来的
        Method[] declaredMethods = clazz.getDeclaredMethods();
        
        Method info = clazz.getDeclaredMethod("info");
        String o = (String) info.invoke(dog);
        System.out.println(o);

    }
}
通过反射调用构造器
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

public class Ch07 {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Dog> clazz = Dog.class;
        // 获得所有公共的构造方法
        Constructor<?>[] constructors = clazz.getConstructors();
        // 获得指定的构造方法,()中可传入参数类型,未传入则获得的为无参构造方法
        Constructor<Dog> declaredConstructor = clazz.getDeclaredConstructor();
        // 通过构造器创建对象
        Dog dog = declaredConstructor.newInstance();
    }
}
posted @   怂还嘴硬  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示