学习笔记——注解&&反射
一、学习重点
二、学习内容
单例模式
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方法..."); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)