JavaSE(反射、注解、枚举)

Junit 单元测试

Junit 是一个单元测试框架,可以代替main方法执行其他的方法
作用:可以单独测试一个方法
Junit 是第三方工具,使用需要导入Jar包

junit-4.12.jar
hamcrest-core.jar

package alive.a_junit;

import org.junit.Test;

/**
 * @Author zyj
 * @Date 2024/10/02 18:51
 * @Description
 */
public class T1 {
    @Test
    public void add() {
        System.out.println("add");
    }

    @Test
    public void delete() {
        System.out.println("delete");
    }
}

@Test:不能修饰static的方法
@Test:不能修饰带参数的方法
@Test:不能修饰带返回值的方法

相关注解

@Before:在@Test之前执行,有多少个@Test执行,@Before就执行多少次,用作初始化数据
@After:在@Test之后执行,有多少个@Test执行,@After就执行多少次,用作释放资源使用

package alive.a_junit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * @Author zyj
 * @Date 2024/10/02 19:25
 * @Description
 */
public class T2 {
    @Test
    public void test1() {
        System.out.println("test1");
    }

    @Test
    public void test2() {
        System.out.println("test2");
    }

    @Before
    public void before() {
        System.out.println("before");
    }

    @After
    public void after() {
        System.out.println("after");
    }
}

在这里插入图片描述

@BeforeClass:在@Test之前执行,只执行一次,可以修饰静态方法
@AfterClass:@Test之后执行,只执行一次,可以修饰静态方法

package alive.b_junit;

import java.util.ArrayList;

/**
 * @Author zyj
 * @Date 2024/10/02 19:30
 * @Description
 */
public class PersonController {
    /**
     * 新增人员
     */
    private ArrayList<Person> list = new ArrayList<>();

    public int add(Person person) {
        list.add(person);
        return 1;
    }

    /**
     * 查询人员列表
     *
     * @return
     */
    public ArrayList<Person> getList() {
        return list;
    }

}

package alive.b_junit;

import org.junit.After;
import org.junit.Test;

import java.util.ArrayList;

/**
 * @Author zyj
 * @Date 2024/10/02 19:35
 * @Description
 */
public class T1 {
    public PersonController pc = new PersonController();

    @Test
    public void add() {
        pc.add(new Person(10, "Tom"));
    }

    @After
    public void query() {
        ArrayList<Person> list = pc.getList();
        System.out.println("list = " + list);
    }


}

类的加载机制

① new 对象
② new 子类对象(new 子类对象先初始化父类)
③ 执行main方法
④ 调用静态成员
⑤ 反射,创建class对象
在这里插入图片描述

类加载器-ClassLoader

在JVM中,负责将本地上的Class文件加载到内存的对象ClassLoader;
分类:
BootStrapClassLoader:根类加载器,C语音写的,我们获取不到,也称为引导类加载器,负责Java的核心类加载,比如:System,String等,jre/lib/rt.jar下的类都是核心类
ExtClassLoader:扩展类加载器,负责JRE的扩展目录中的jar包的加载,在JDK中的JRE的lib目录下的ext目录
AppClassLoader:系统类加载器,负责JVM启动时加载来自java命令class文件(自定义类),以及classpath环境变量所指定的jar包(第三方jar包)

不同的类加载器加载不同的类

三者的关系(从类加载机制层面):AppClassLoader的父类加载器是ExtClassLoader,ExtClassLoader的父类加载器是BootStrapClassLoader
他们从代码级别上来看,没有子父类继承关系,他们都有一个共同的父类 ClassLoader

获取类加载器对象
getClassLoader()是class对象中的方法
类名.getClassLoader()

获取类加载器对象对应的父类加载器
ClassLoader类中的方法:ClassLoader
getParent()

package alive.c_class_loader;

import org.junit.internal.builders.JUnit3Builder;

import javax.net.ssl.SNIServerName;

/**
 * @Author zyj
 * @Date 2024/10/02 20:30
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        app();
        ext();
        boot();
    }

    /**
     * 自定义类以及第三方jar中的类
     */
    public static void app() {
        System.out.println("T1.class.getClassLoader() = " + T1.class.getClassLoader());
        //T1.class.getClassLoader() = jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
        System.out.println("JUnit3Builder.class.getClassLoader() = " + JUnit3Builder.class.getClassLoader());
        //JUnit3Builder.class.getClassLoader() = jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
        System.out.println("JUnit3Builder.class.getClassLoader().getParent() = " + JUnit3Builder.class.getClassLoader().getParent().getParent());
    }

    /**
     * 扩展类加载器
     */
    public static void ext() {
        System.out.println("SNIServerName.class.getClassLoader() = " + SNIServerName.class.getClassLoader());
    }

    /**
     * rt.jar包中的类
     * BootStrapClassLoader 是C语言编写,我们获取不到
     */
    public static void boot() {
        System.out.println("String.class.getClassLoader().getParent() = " + String.class.getClassLoader());
    }
}

双亲委派机制(全盘负责委托机制)
① Person类中有一个String
② Person本身是AppClassLoader加载
③ String是BootStrapClassLoader加载
加载顺序:
Person本身是App加载,按理来说String也是App加载
但是App加载String的时候,先问一问Ext:你加载String吗?
Ext说:我不加载,我负责加载的是扩展类,但是app你别着急,我去问父类 boot
Ext说:boot,你加载String吗?
boot:我加载核心类ok,我加载去了

类加载器的cache(缓存)机制(扩展):一个类加载到内存中,缓冲也会保存一份,后面如果再使用此类,如果缓存中保存了这个类,直接返回,如果没有才加载这个类,下次如果有其他类在使用的时候就不会重新加载了,直接去缓存中拿,保证在内存中的唯一性

所以:类加载器的双亲委派和缓存机制共同造就了加载类的特点,保证了类在内存中的唯一性。

在这里插入图片描述

反射

反射概述:解刨class对象的一个技术

获取Class对象

  1. 调用Object中的getClass方法
    Class <?> getClass()
  2. 无论是基本类型还是引用类型,JVM都提供了一个静态成员:class
  3. Class类中的静态方法
    static Class<?> forName(String className)
    className:传递的是类的全限定名(包名.类名)
package alive.d_reflect;

import org.junit.Test;

/**
 * @Author zyj
 * @Date 2024/10/02 22:00
 * @Description
 */
public class T1 {

    @Test
    public void get() throws ClassNotFoundException {
        Person person = new Person();
        Class<? extends Person> aClass = person.getClass();
        System.out.println("aClass = " + aClass);
        Class<Person> personClass = Person.class;
        Class<?> aClass1 = Class.forName("alive.d_reflect.Person");
        System.out.println("aClass1 = " + aClass1);
    }
}

  • pro.properties
className=alive.d_reflect.Person
package alive.d_reflect;

import java.io.FileInputStream;
import java.util.Properties;

/**
 * @Author zyj
 * @Date 2024/10/03 11:53
 * @Description
 */
public class T2 {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        FileInputStream is = new FileInputStream("Junit\\pro.properties");
        properties.load(is);
        String className = properties.getProperty("className");
        System.out.println("className = " + className);
        Class<?> aClass = Class.forName(className);
        System.out.println("aClass = " + aClass);
    }
}
  • 常用的:类名.class

反射构造方法

获取所有public的构造方法

Class类中的方法
Construct<?>[] getConstructors():获取所有public的构造

package alive.d_reflect;

import java.lang.reflect.Constructor;

/**
 * @Author zyj
 * @Date 2024/10/03 12:00
 * @Description
 */
public class T3 {
    public static void main(String[] args) {
        // ① 获取class对象
        Class<Person> personClass = Person.class;
        // ② 获取所有的public的构造
        Constructor<?>[] constructors = personClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("constructor = " + constructor);
        }
    }
}

获取空参构造方法

Class 类中的方法:
Constructor< T > getConstructor(Class< ? >... parameterTypes):获取指定的public的构造
parameterTypes:可变参数,可以传递0个或者多个参数
① 如果获取的是空参构造:参数不用写
② 如果获取的是有参构造:参数写参数类型的class对象

Constructor类中的方法
T newInstance(Object… initargs):创建对象
initargs:传递的是构造方法的实参
① 如果根据无参构造new对象,initargs不用写
② 如果根据有参构造new对象,initargs传递实参

package alive.d_reflect;

import java.lang.reflect.Constructor;

/**
 * @Author zyj
 * @Date 2024/10/03 12:13
 * @Description
 */
public class T4 {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Constructor<Person> constructor = personClass.getConstructor();
        Person person = constructor.newInstance();
        System.out.println("person = " + person);
    }
}

空参构造创建对象的快捷方式

Class类中的方法:
T newInstance():根据空参构造创建对象
前提:被反射的类中必须有public修饰的空参构造

package alive.d_reflect;

/**
 * @Author zyj
 * @Date 2024/10/03 12:17
 * @Description
 */
public class T5 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        Class<Person> personClass = Person.class;
        Person person = personClass.newInstance();
        System.out.println("person = " + person);
    }
}

获取有参构造方法

package alive.d_reflect;

import java.lang.reflect.Constructor;

/**
 * @Author zyj
 * @Date 2024/10/03 12:20
 * @Description
 */
public class T6 {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Constructor<Person> constructor = personClass.getConstructor(Integer.class, String.class);
        Person person = constructor.newInstance(19, "Tom");
        System.out.println("person = " + person);

    }
}

package alive.d_reflect;

/**
 * @Author zyj
 * @Date 2024/10/02 21:56
 * @Description
 */
public class Person {
    public Person() {
    }

    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    private Integer age;
    private String name;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

获取私有构造

Constructor<?>[] getDeclaredConstructors():获取所有的构造方法,包括private
Constructor< T > getDeclaredConstructor(类< ? >... parameterTypes):获取指定构造,包括private
parameterTypes 参数类型的class对象

Constructor 有一个父类 AccessibleObject,里面有一个方法
void setAccessible(boolean flag):修改访问权限
flag true:解除私有权限

package alive.d_reflect;

import java.lang.reflect.Constructor;

/**
 * @Author zyj
 * @Date 2024/10/03 12:38
 * @Description
 */
public class T7 {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        // 获取所有的
        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("declaredConstructor = " + declaredConstructor);
        }
        // 获取指定的
        Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class);
        declaredConstructor.setAccessible(true);
        Person person = declaredConstructor.newInstance("Jack");
        System.out.println("person = " + person);
    }
}

package alive.d_reflect;

/**
 * @Author zyj
 * @Date 2024/10/02 21:56
 * @Description
 */
public class Person {
    public Person() {
    }

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

    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    private Integer age;
    private String name;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

反射成员方法

获取所有的成员方法_public

Class类中的方法
Methodp[[ getMethods:获取所有public的方法,包括父类中的public方法

package alive.d_reflect;

import java.lang.reflect.Method;

/**
 * @Author zyj
 * @Date 2024/10/03 13:48
 * @Description
 */
public class T8 {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println("method = " + method);
        }
        //method = public java.lang.String alive.d_reflect.Person.getName()
        //method = public java.lang.String alive.d_reflect.Person.toString()
        //method = public void alive.d_reflect.Person.setName(java.lang.String)
        //method = public java.lang.Integer alive.d_reflect.Person.getAge()
        //method = public void alive.d_reflect.Person.setAge(java.lang.Integer)
        //method = public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
        //method = public final void java.lang.Object.wait() throws java.lang.InterruptedException
        //method = public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
        //method = public boolean java.lang.Object.equals(java.lang.Object)
        //method = public native int java.lang.Object.hashCode()
        //method = public final native java.lang.Class java.lang.Object.getClass()
        //method = public final native void java.lang.Object.notify()
        //method = public final native void java.lang.Object.notifyAll()
    }
}

获取方法(有参、无参)_public

Class类中的方法
Method getMethod(String name,Class<?>... parameterTypes):获取指定的public的成员方法
name:方法名
parameterType:方法参数类型的class对象

调用方法:Method对象中的方法
Object invoke(Object obj,Object... args):执行方法
obj:根据构造new出来的对象
args:方法实参,有参数直接传递实参,否则不用传
返回值:Object:接受被执行方法的返回值,如果方法没有返回值,不用接受

package alive.d_reflect;

import java.lang.reflect.Method;

/**
 * @Author zyj
 * @Date 2024/10/03 13:54
 * @Description
 */
public class T9 {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Person person = personClass.newInstance();
        Method setName = personClass.getMethod("setName", String.class);
        System.out.println("setName = " + setName);
        setName.invoke(person, "Tom");
        System.out.println("person = " + person);
        Method getName = personClass.getMethod("getName");
        Object name = getName.invoke(person);
        System.out.println("name = " + name);
    }
}

获取私有方法

Method[] getDeclaredMethods():获取所有的成员方法,包括private
Method getDeclaredMethod(String name,类<?>... parameterTypes):获取执行成员方法,包括private
name:传递方法名
parameterType:方法参数类型的class对象

void setAccessible(boolean flag):解除私有权限

package alive.d_reflect;

import java.lang.reflect.Method;

/**
 * @Author zyj
 * @Date 2024/10/03 14:07
 * @Description
 */
public class T10 {
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Person person = personClass.newInstance();
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("declaredMethod = " + declaredMethod);
        }
        Method eat = personClass.getDeclaredMethod("eat");
        eat.setAccessible(true);
        eat.invoke(person);
    }
}

反射成员变量

获取所有属性

Class类中的方法
Field[] getFields():获取所有public的属性
Field getDeclaredFields():获取所有属性,包括private

package alive.d_reflect;

import java.lang.reflect.Field;

/**
 * @Author zyj
 * @Date 2024/10/03 14:16
 * @Description
 */
public class T11 {
    public static void main(String[] args) {
        Class<Student> studentClass = Student.class;
        Field[] fields = studentClass.getFields();
        for (Field field : fields) {
            System.out.println("field = " + field);
        }
        Field[] declaredFields = studentClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("declaredField = " + declaredField);
        }
    }
}

获取指定属性

Class类中的方法
Field[] getField(String name):获取指定public的属性
Field getDeclaredField(String name):获取指定属性,包括private

Filed类中的方法
void set(Object obj,Object value):为属性赋值,相当于JavaBean中的set方法
obj:对象
value:值
Object get(Object obj):获取属性值
obj:对象

void setAccessible(boolean flag):解除私有权限

package alive.d_reflect;

import java.lang.reflect.Field;

/**
 * @Author zyj
 * @Date 2024/10/03 14:25
 * @Description
 */
public class T12 {
    public static void main(String[] args) throws Exception {
        Class<Student> studentClass = Student.class;
        Student student = studentClass.newInstance();
        Field age = studentClass.getField("age");
        age.set(student, 10);
        Object o = age.get(student);
        System.out.println("o = " + o);
        Field name = studentClass.getDeclaredField("name");
        name.setAccessible(true);
        name.set(student, "Tom");
        Object o1 = name.get(student);
        System.out.println("o1 = " + o1);
        System.out.println("student = " + student);
    }
}

反射练习

需求:在配置文件中,配置类的全限定名,以及配置一个方法名,通过解析配置文件,让配置好的方法执行起来
className = 包名.Person
methodName = eat

步骤:

  1. 创建properties配置文件,配置信息
    ① properties配置文件放哪里?
    将来我们开发完成之后,输出的是out路径下的class文件,将class文件打包,如果将配置文件直接放到模块下,那么out路径下是不会生成这个配置文件的,如果没有配置文件,程序也就运行不起来。
    解决:我们可以将配置文件放到src目录下,out路径下就会出现配置文件
    ② 将配置文件放到src下,out路径下会自动生成配置文件
    解决:我们可以单独创建一个文件夹,将所有的配置文件放到此目录下,将文件改成资源目录,取名resources
  2. 读取配置文件,解析配置文件
    ① 如果配置文件放到resources资源目录下,怎么读取
    使用 ``new FileInputStream(“模块名称\resource\properties文件名”),这样是不可取的,out路径下没有resource目录
    解决:使用类加载器
    ClassLoader classLoader = 当前类.class.getClassLoader()
    InputStream in = classLoader.getResourceAsStream(“文件名”):自动扫描resource下的文件,扫描out路径下的配置文件
  3. 根据解析出来的className,创建一个Class对象
  4. 根据解析出来的methodName,获取对应的方法
  5. 执行方法
className=alive.e_pro.Person
methodName=sleep
package alive.e_pro;

/**
 * @Author zyj
 * @Date 2024/10/03 17:34
 * @Description
 */
public class Person {
    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    private String name;

    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void eat() {
        System.out.println("eat.........");
    }

    public void sleep() {
        System.out.println("sleep........");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

package alive.e_pro;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @Author zyj
 * @Date 2024/10/03 17:37
 * @Description
 */
public class T1 {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        InputStream is = T1.class.getClassLoader().getResourceAsStream("pro.properties");
        properties.load(is);
        System.out.println("properties = " + properties);
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");
        Class<?> aClass = Class.forName(className);
        Object o = aClass.newInstance();
        Method method = aClass.getMethod(methodName);
        method.invoke(o);
    }
}

注解

  1. 引用数据类型:
    类、数组、接口、枚举、注解
  2. JDK 1.5 版本的新特性,一个应用数据类型,和类、接口、枚举是同一个层次
  3. 作用:
    说明:对代码进行说明,上传doc文档(API文档)
    检查:检查代码是否符合条件@Override@FunctionalInterface
    分析:对代码进行分析,起到代替配置文件的作用

注解的定义以及属性的定义格式

public @interface Book {

}

注解属性其本质是抽象方法;
增强注解的使用
数据类型 属性名():此属性没有默认值,需要在使用注解的时候为其赋值
数据类型 属性名() default 值:此属性有默认值,可二次赋值

注解能定义的数据类型:
① 8种基本类型
② String类型、class类型、枚举类型、注解类型
③ 以上类型的一维数组

package alive.f_annotation;

public @interface Book {
    String bookName();
    String[] author();
    int price();
    int count();
}

注解的使用

为注解中的属性赋值
使用位置:类、方法、成员变量、成员方法、局部变量、参数位置

使用格式:
@注解名(属性名 = 值,属性名 = 值)
@注解名(属性名 = {元素1,元素2,..........})

package alive.f_annotation;

public @interface Book {
    String bookName();

    String[] author();

    int price();

    int count() default 10;
}

package alive.f_annotation;

/**
 * @Author zyj
 * @Date 2024/10/04 12:48
 * @Description
 */
@Book(bookName = "三国演义", author = {"罗贯中"}, price = 100, count = 20)
public class BookShelf {
}

注意:

  1. 空注解可以直接使用:空注解就是注解中没有任何属性
  2. 不同的位置可以使用一样的注解,但是同样的位置不能使用一样的注解
  3. 使用注解时,如果注解中有属性,注解中的属性一定要赋值,如果是多个属性,用,隔开,注解中使用数组,使用{}
  4. 如果注解中的属性有默认值,可不写,
  5. 如果注解中只有一个属性,并且属性名叫value,那么使用注解的时候,属性名不用写,可直接写值(包括单个类型和数组)
package alive.f_annotation;

public @interface action {
    String value();
}

package alive.f_annotation;

/**
 * @Author zyj
 * @Date 2024/10/04 12:48
 * @Description
 */
@Book(bookName = "三国演义", author = {"罗贯中"}, price = 100, count = 20)
@action("look")
public class BookShelf {
}

注解解析

获取到注解中的属性值

  1. 注解解析涉及的接口:AnnotateElement接口
    实现类:AccessibleObject、Class、Constructor、Executable、Field、Method、Package、Parameter
  2. 解析
    ① 先判断指定位置上有没有使用指定的注解
    boolean isAnnotationPresent(Class<? extends Annotation> annotationClass):判断指定位置上有没有指定的注解
    getAnnotation(Class<T> annotationClass):获取指定注解,返回值类型为获取的注解类型
    ② 获取注解中的属性值
 package alive.g_annotation;

/**
 * @Author zyj
 * @Date 2024/10/04 13:55
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        boolean annotationPresent = personClass.isAnnotationPresent(Action.class);
        if (annotationPresent) {
            Action annotation = personClass.getAnnotation(Action.class);
            int age = annotation.age();
            String name = annotation.name();
            System.out.println("name = " + name);
            System.out.println("age = " + age);
        }
    }
}

package alive.g_annotation;

public @interface Action {
    String name();

    int age();

}

package alive.g_annotation;

/**
 * @Author zyj
 * @Date 2024/10/04 13:57
 * @Description
 */
@Action(name = "Tom", age = 11)
public class Person {

}

Action注解没有被加载至内存中,annotationPresent是false

元注解

元注解就是管理注解的注解

  1. 控制注解的使用位置
    ① 控制注解能否在类上使用
    ② 控制注解能否在构造上使用
    ③ 控制注解能否在方法上使用
  2. 控制注解的生命周期(加载位置)
    ① 控制注解能否在源码中出现
    ② 控制注解能否在class文件中出现
    ③ 控制注解能否在内存中出现

使用:

  1. @Target:控制注解的使用位置
    ElementType[] value():是一个枚举,里面的成员可以类名直接调用
    ElementType成员:
    TYPE:控住注解能使用在类上
    FIELD:控制注解能使用在属性上
    METHOD:控制注解能使用在方法上
    PARAMETER:控制注解能使用在参数上
    CONSTRUCTOR:控制注解能使用在构造上
    LOCAL_VARIABLE:控住注解能使用在局部变量上
  2. @Retention:控制注解的生命周期
    RetentionPolicy value():是一个枚举,成员可以直接类名调用
    RetentionPolicy 成员:
    SOURCE:控制注解能在源码中出现默认
    CLASS:控制注解能在Class文件中出现
    RUNTIME:控制注解能在运行时出现
package alive.g_annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
    String name();

    int age();

}

package alive.g_annotation;

/**
 * @Author zyj
 * @Date 2024/10/04 13:55
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        boolean annotationPresent = personClass.isAnnotationPresent(Action.class);
        if (annotationPresent) {
            Action annotation = personClass.getAnnotation(Action.class);
            int age = annotation.age();
            String name = annotation.name();
            System.out.println("name = " + name);
            System.out.println("age = " + age);
        }
    }
}

枚举

五大引用类型
定义:
public enum 枚举类名{}
所有的枚举类都是Enum

枚举的特点:
都是 static final,定义的时候不写,
写完所有枚举加;
枚举名称大写
使用:类名直接调用
注意:每一个枚举都是当前枚举类对象

枚举类中的枚举值都是本类类型
在枚举类中定义的构造,默认都是private
使用场景:表示对象的状态

方法名说明
String toString()返回枚举值的名称
values()返回所有的枚举值
valueOf(String str)将一个字符串转成枚举类型
package alive.h_enum;

public enum State {
    FINISHED(1),
    UNFINISHED(2),
    ACTION(3);
    private Integer value;

    State(Integer value) {
        this.value = value;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }
}

package alive.h_enum;

/**
 * @Author zyj
 * @Date 2024/10/04 14:50
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        State finished = State.FINISHED;
        System.out.println("finished = " + finished);
        //finished = FINISHED
        System.out.println("finished.toString() = " + finished.toString());
        State[] values = State.values();
        for (State value : values) {
            System.out.println("value = " + value);
        }
        State f = State.valueOf("FINISHED");
        System.out.println("f = " + f.getValue());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值