注解
注解和注释的区别
注解 annotation
写在程序之中,程序可以识别,做出相应的动作处理,具有检查和约束程序的作用
注释 comment
写在程序之中,供人参考,提示使用,程序会自动忽略
注解在JDK5
开始引入
常见注解
@Override
重写一个方法
@Deprecated
不推荐使用
@SuppressWarnings("all")
镇压警告
元注解
元注解就是可以负责注解其他的注解
@Target
描述注解的使用范围
@Retention
表示在什么级别保存该注解信息(Source < Class < Runtime)
@Document
该注解被包含在javadoc
中
@Inherited
说明子类可以继承父类中的注解
自定义注解
@MyAnnotation(value = "User MyAnnotation", university = "家里蹲大学", age = 666)
public class User {
@MyAnnotation(name = "main Method", age = 18, id = 1, university = "复旦大学", value = "main MyAnnotation")
public static void main(String[] args) throws NoSuchMethodException {
Class<User> userClass = User.class;
System.out.println("==============method===============");
Method main = userClass.getMethod("main", String[].class);
if (main.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = main.getAnnotation(MyAnnotation.class);
System.out.println(annotation.age());
System.out.println(annotation.id());
System.out.println(Arrays.toString(annotation.university()));
System.out.println(annotation.name());
System.out.println(annotation.value());
}
System.out.println("==============class===============");
if (userClass.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = userClass.getAnnotation(MyAnnotation.class);
System.out.println(annotation.age());
System.out.println(annotation.id());
System.out.println(Arrays.toString(annotation.university()));
System.out.println(annotation.name());
System.out.println(annotation.value());
}
}
}
@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation {
String name() default "name";
int age() default 0;
// -1 代表不存在
int id() default -1;
String[] university() default {"清华大学", "北京大学"};
String value();
}
运行结果
注解级别
@Table("Anno类")
public class Anno {
@Feild("用户名")
private String username;
@Method("main函数")
public static void main(String[] args) {}
}
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
@interface Table{
String value();
}
@Target(value = ElementType.FIELD)
@Retention(value = RetentionPolicy.RUNTIME)
@interface Feild{
String value();
}
@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@interface Method{
String value();
}
查看ElementType
枚举类的源码如下
package java.lang.annotation;
public enum ElementType{
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE,
MODULE;
private ElementType() {
}
}
这个枚举类实现了单例模式,构造器私有
属性
TYPE
public static final ElementType TYPE
类,接口(包括注释类型)或枚举声明
FIELD
public static final ElementType FIELD
字段声明(包括枚举常数)
METHOD
public static final ElementType METHOD
方法声明
PARAMETER
public static final ElementType PARAMETER
正式参数声明
CONSTRUCTOR
public static final ElementType CONSTRUCTOR
构造函数声明
LOCAL_VARIABLE
public static final ElementType LOCAL_VARIABLE
局部变量声明
ANNOTATION_TYPE
public static final ElementType ANNOTATION_TYPE
注解类型声明
PACKAGE
public static final ElementType PACKAGE
包装声明
TYPE_PARAMETER
public static final ElementType TYPE_PARAMETER
键入参数声明
TYPE_USE
public static final ElementType TYPE_USE
使用类型
MODULE
public static final ElementType MODULE
模块声明,jdk11
具有的
反射
反射 reflection
,一个类在内存中只存在一个class
对象,一个类被加载之后,类的整个结构都会封装在Class
对象中
public class ReflectionDemo {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> aClass = Class.forName("com.mao.pojo.User");
Class<?> bClass = Class.forName("com.mao.pojo.User");
Class<?> cClass = Class.forName("com.mao.pojo.User");
System.out.println(aClass.hashCode());
System.out.println(bClass.hashCode());
System.out.println(cClass.hashCode());
}
}
class User{
private String username;
private String password;
}
获取class对象
public static void main(String[] args) throws ClassNotFoundException {
User user = new User();
System.out.println(user);
// 对象获取
Class aClass = user.getClass();
System.out.println(aClass.hashCode());
// forName 获取
Class bClass = Class.forName("com.mao.pojo.User");
System.out.println(bClass.hashCode());
// 类.class
Class<User> cClass = User.class;
System.out.println(cClass.hashCode());
// 基本数据类型的包装类获得
Class<Integer> type = Integer.TYPE;
System.out.println(type);
System.out.println(type.getSuperclass());
System.out.println(aClass.getSuperclass());
}
所有类型的Class对象
public static void main(String[] args) throws ClassNotFoundException {
System.out.println(Object.class);
System.out.println(Comparable.class);
System.out.println(String[].class);
System.out.println(int[][].class);
System.out.println(Override.class);
System.out.println(Integer.class);
System.out.println(void.class);
System.out.println(Class.class);
System.out.println(new int[10].getClass().hashCode());
System.out.println(new int[100].getClass().hashCode());
}
结果是
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.Integer
void
class java.lang.Class
750044075
750044075
查看类加载器
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
ClassLoader classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
}
jdk.internal.loader.ClassLoaders A p p C l a s s L o a d e r @ 2437 c 6 d c j d k . i n t e r n a l . l o a d e r . C l a s s L o a d e r s AppClassLoader@2437c6dc jdk.internal.loader.ClassLoaders AppClassLoader@2437c6dcjdk.internal.loader.ClassLoadersPlatformClassLoader@2cb4c3ab
null
null
获取java
运行放入环境
获取类运行时的结构
public class ReflectionDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Class className = Class.forName("com.mao.pojo.User");
System.out.println(className.getClass());
System.out.println(className.getSimpleName());
System.out.println("=============================");
User user = new User();
className = user.getClass();
System.out.println(className.getClass());
System.out.println(className.getSimpleName());
System.out.println(className.getField("username"));
System.out.println(className.getField("password"));
}
}
class User{
public String username;
private String password;
}
获取构造器
Class className = Class.forName("com.mao.pojo.User");
Constructor[] constructors = className.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
constructors = className.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
通过构造器创建对象
Class classObject = Class.forName("com.mao.pojo.User");
// newInstance() 需要无参构造器,且防蚊权限足够
User user = (User) classObject.newInstance();
System.out.println(user);
Constructor constructor = classObject.getDeclaredConstructor(String.class,String.class);
User root = (User)constructor.newInstance("root", "123456");
System.out.println(root);
反射获取到类对象,创建实例,获取到方法的set
方法,通过invoke
激活,对对对象设置值
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
Class classObject = Class.forName("com.mao.pojo.User");
User user = (User) classObject.newInstance();
Method setUsername = classObject.getDeclaredMethod("setUsername", String.class);
setUsername.invoke(user,"root");
System.out.println(user.getUsername());
}
反射将私有属性进行访问
Class classObject = Class.forName("com.mao.pojo.User");
User user = (User) classObject.newInstance();
Field username = classObject.getDeclaredField("username");
// 破解 private,取消安全检测
username.setAccessible(true);
username.set(user,"admin");
System.out.println(user.getUsername());
对比正常使用创建对象,反射创建对象,设置可见性的方式对比性能,结果发现new方式创建对象的方式最快,反射创建对象的时间最长,关闭检查,性能可提高一倍
public class ReflectionDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
// 普通方式
User user = new User();
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
user.getUsername();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
// 反射获取方法
Class aClass = Class.forName("com.mao.pojo.User");
Method getUsername = aClass.getDeclaredMethod("getUsername", null);
long start1 = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getUsername.invoke(user,null);
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1);
// 反射获取方法,关闭检查
Class bClass = Class.forName("com.mao.pojo.User");
Method getUsername1 = bClass.getDeclaredMethod("getUsername", null);
getUsername1.setAccessible(true);
long start2 = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getUsername1.invoke(user,null);
}
long end2 = System.currentTimeMillis();
System.out.println(end2 - start2);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class User{
private String username;
private String password;
}