学习笔记——注解&&反射

一、学习重点

 

二、学习内容

单例模式

复制代码
import java.lang.annotation.*;

/**
 * 只要用这个注解标注的类,就是单例的
 * 无法通过反射来创建对象
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Singleton {

    boolean value() default true;
}
复制代码
复制代码
import java.lang.reflect.InvocationTargetException;

@Singleton
public class Factory {

    private static Factory factory = new Factory();

    static {
        Class<? extends Factory> clazz = factory.getClass();
        Singleton annotation = clazz.getAnnotation(Singleton.class);
        boolean value = annotation.value();
        if(value) {
            try {
                Factory factory1 = clazz.getDeclaredConstructor().newInstance();
                if(factory1 != null) {
                    throw new RuntimeException("该类为单例模式,无法创建对象");
                }
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            }
        }

    }

    private Factory(){}

    public static Factory getInstance() {

        return factory;
    }
}
复制代码

用户

复制代码
import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface UserMapping {

    String username();

    String password();

}
复制代码
复制代码
public class User {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
复制代码
复制代码
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class UserController {

     {
        Class<UserController> clazz = UserController.class;
        try {
            Method addUser = clazz.getDeclaredMethod("addUser", User.class);
            UserMapping annotation = addUser.getAnnotation(UserMapping.class);
            String username = annotation.username();
            String password = annotation.password();

            User user = new User(username,password);

            addUser.invoke(this,user);

        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
     }

    @UserMapping(username = "admin",password = "123456")
    public void addUser(User user){
        System.out.println(user);
    }

    public static void main(String[] args) {
        UserController userController = new UserController();
    }
}
复制代码

三、笔记内容

注解和反射
注解:Annotation,Java标注,JDK5引入的一种机制。
Java中类,方法,变量,参数,包都可以被标注
元注解:专门给注解加的注解
我们发现注解中可以有方法,
1、定义方法的格式:String name();
2、可以有默认值,也可以没有,如果没有默认值在使用的时候必须填写对应的值
如果需要有默认值,使用default指定默认值。
3、如果想在使用的时候不指定具体的名字,
如果不学习反射,注解没啥用!!!
在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编辑器去忽略警告
4、@SafeVarargs,JDK7支持忽略任何使用参数为泛型变量的方法或构造器产生的警告
5、@FunctionalInterface,JDK8开始支持,表示一个接口为函数式接口
6、@Repeatable,JDK8开始支持,标识某个注解可以在同一个声明上使用多次
all:忽略所有警告
boxing:忽略装箱、拆箱警告
rawtypes:使用生成时没有指定数据类型
unchecked:忽略没有进行类型检查操作的警告
unused:忽略没有使用的警告
元注解:
1、@Retention:标识这个注解作用域
2、@Documented:标记这个注解是否包含在用户文档中
3、@Target:这个注解可以修饰哪些信息
4、@Inherited:如果一个类用上了@Inherited注解,那么其子类也会继承这个注解

复制代码
import java.lang.annotation.*;

/**
 * 这是我们自己创建的注解
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MyAnnotation {

    String name() default "tom";
    int age();
    int value();
}
复制代码
复制代码
public class Ch01 {

    @Deprecated
    @SuppressWarnings("all")
    public void info() {

    }

    @MyAnnotation(value = 20,age = 15)
    public void show(){
        info();
//        new Date(2000,12,23);
    }

    @Override
    public String toString() {
        return super.toString();
    }
}
复制代码

反射——class类

复制代码
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        // 获取类对象
        // 1.直接使用类名.class
        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();

        // 2.使用全类名
//        Class aClass = Class.forName("com.jsoft.morning.Dog");
        // 3.使用对象
//        Dog dog = new Dog();
//        Class aClass1 = dog.getClass();
    }
复制代码

 

复制代码
    public static void main(String[] args) throws NoSuchFieldException {
        // 对成员变量的操作
        Class<Dog> clazz = Dog.class;
        // 只能获取到public的属性
        Field type = clazz.getField("type");
        System.out.println(type);
        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));
    }
复制代码

获取对象的属性

复制代码
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Dog dog = new Dog();
        dog.setType("金毛");
        Dog dog1 = new Dog();
        dog1.setType("泰迪");
        Class<Dog> clazz = Dog.class;
        Field type = clazz.getDeclaredField("type");
        // 想要获取哪一个对象的color
        String str = (String) type.get(dog1);
        System.out.println(str);
    }
复制代码
复制代码
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Dog dog = new Dog();
        dog.setType("萨摩耶");
        Class clazz = Dog.class;
        Field type = clazz.getDeclaredField("type");
        type.set(dog,"拉布拉多");

        System.out.println(dog.getType());

        Field color = clazz.getDeclaredField("color");
        // 暴力注入
        color.setAccessible(true);
        color.set(dog,"black");
        System.out.println(dog.getColor());

    }
复制代码

 通过反射调用构造器

复制代码
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Dog> clazz = Dog.class;
        Constructor<?>[] constructors = clazz.getConstructors();
//        System.out.println(Arrays.toString(constructors));
        Constructor<Dog> declaredConstructor = clazz.getDeclaredConstructor();
        // 通过构造器创建对象
        Dog dog = declaredConstructor.newInstance();

        // 单例模式
        // 1.构造器私有化
        Constructor<Dog> declaredConstructor1 = clazz.getDeclaredConstructor(String.class);
        declaredConstructor1.setAccessible(true);
        Dog dog1 = declaredConstructor1.newInstance("小强");
        System.out.println(dog1.getName());
    }
复制代码
import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Bean {
}
复制代码
    public static void main(String[] args) throws NoSuchMethodException {

        Class<Dog> clazz = Dog.class;
        Bean annotation = clazz.getAnnotation(Bean.class);
        Annotation[] annotations = clazz.getAnnotations();
//        System.out.println(Arrays.toString(annotations));
        Method show = clazz.getDeclaredMethod("show", String.class);
        MyAnnotation annotation1 = show.getAnnotation(MyAnnotation.class);
        System.out.println(annotation1.age());
    }
复制代码

 

复制代码
@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方法...");
    }
}
复制代码

 

posted @   LJMMJL  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示