注解与反射
内置注解
@Override:重写超类的方法声明
@Deprecated:不鼓励使用
@SuppressWarnings:用来抑制编译时的警告信息(需要加参数)例如“all”
package com.zzw.annotation;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("all")//镇压警告,适用于任何地方
public class Test01 extends Object {
@Override//重写注解
public String toString() {
return super.toString();
}
@Deprecated //不推荐使用
public static void test() {
System.out.println("Deprecated");
}
public void test02() {
List<Object> list = new ArrayList<>();
}
public static void main(String[] args) {
test();
}
}
元注解(meta-annotation)
@Target:表示注解可以在什么地方被使用。
@Retention:表示什么时间有效
@Document:表示在Javadoc文档中生成
@Inherited:表示子类可以继承父类的此注解
package com.zzw.annotation;
import java.lang.annotation.*;
@Myannotation
public class Test02 {
public void test() {}
}
//Target表示我们可以在哪里使用注解
@Target(value = {ElementType.METHOD, ElementType.TYPE})
//Retention表示注解在什么时间有效
@Retention(value = RetentionPolicy.RUNTIME)
//是否把我们的注解声称在Javadoc中
@Documented
//可以被子类继承
@Inherited
@interface Myannotation{
}
自定义注解
package com.zzw.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class Test03 {
@Myannotation2()
public void test() {
}
@Myannotation3("邹智威")
public void test02() {
}
}
@Target(value = {ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Myannotation2{
String name() default "邹智威";
int id() default 11;
int age() default 18;
String[] school() default {"广州大学", "华软大学"};
}
@Target(value = {ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Myannotation3{
String value();
}
小结:
- 自定义注解中的是参数,不是方法
- 参数必须在注解中传入参数,否则报错
- 若有默认参数,不需传入也可以
- 若只有一个参数,且参数名为value,可以不用写参数名
- 传入参数不用按顺序
获取反射信息
package com.zzw.reflection;
public class test02 {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c1 = Class.forName("com.zzw.reflection.User");
System.out.println(c1);
}
}
class User {
private String name;
private int age;
private int is;
public User() {
}
public User(String name, int age, int is) {
this.name = name;
this.age = age;
this.is = is;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getIs() {
return is;
}
public void setIs(int is) {
this.is = is;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", is=" + is +
'}';
}
}
获取Class类
package com.zzw.reflection;
public class test03 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println(person);
//1.通过对象获取类信息
Class aClass = person.getClass();
System.out.println(aClass.hashCode());
//2.通过类名获取
Class<Student> studentClass = Student.class;
System.out.println(studentClass.hashCode());
//3.通过forName获取
Class<?> aClass1 = Class.forName("com.zzw.reflection.Student");
System.out.println(aClass1.hashCode());
//4.内置数据类型有TYPE
Class<Integer> type = Integer.TYPE;
System.out.println(type);
//5.获取父类
Class superclass = aClass.getSuperclass();
System.out.println(superclass.hashCode());
}
}
class Person{
String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class Student extends Person{
public Student() {
this.name = "学生";
}
}
class Teacher extends Person {
public Teacher() {
this.name = "老师";
}
}
不同对象类型的Class
package com.zzw.reflection;
import java.lang.annotation.ElementType;
public class Test04 {
public static void main(String[] args) {
Class<Object> objectClass = Object.class;
Class<Comparable> comparableClass = Comparable.class;
Class<String[]> aClass = String[].class;
Class<int[][]> aClass1 = int[][].class;
Class<Override> overrideClass = Override.class;
Class<ElementType> elementTypeClass = ElementType.class;
Class<Integer> integerClass = Integer.class;
Class<Void> voidClass = void.class;
Class<Class> classClass = Class.class;
System.out.println(objectClass);
System.out.println(comparableClass);
System.out.println(aClass);
System.out.println(aClass1);
System.out.println(overrideClass);
System.out.println(elementTypeClass);
System.out.println(integerClass);
System.out.println(voidClass);
System.out.println(classClass);
}
}
内存加载分析
package com.zzw.reflection;
public class Test05 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
class A {
static {
System.out.println("A类静态代码块初始化");
m = 100;
}
static int m = 300;
public A() {
System.out.println("A类的无参构造函数初始化");
}
}
个人分析:静态变量和静态方法,常量都在堆中,方法区中生成包含这个类的java.lang.Class信息,实例对象通过找到java.lang.Class找到类的数据
主动引用与被动引用
package com.zzw.reflection;
public class Test06 {
static {
System.out.println("main类被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
//1.主动引用
// Son son = new Son();
//2.反射也会主动引用
// Class.forName("com.zzw.reflection.Son");
//不产生引用
// System.out.println(Son.b);
// Son[] sons = new Son[5];
System.out.println(Son.M);
}
}
class Father {
static int b = 2;
static {
System.out.println("父类被加载");
}
}
class Son extends Father {
static {
System.out.println("子类被加载");
m = 100;
}
static int m = 300;
static final int M = 1;
}
小结:
主动引用:
- new一个对象
- 反射
被动引用
- 父类的静态变量
- 数组
- 常量
类加载器
package com.zzw.reflection;
public class Test07 {
public static void main(String[] args) throws ClassNotFoundException {
//1.系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//2.扩展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
//3.启动类加载器
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
//测试当前类是那个加载器加载的
ClassLoader classLoader = Class.forName("com.zzw.reflection.Test07").getClassLoader();
System.out.println(classLoader);
//测试JDK内置类是谁加载的
ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader1);
/*
C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;
C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;
C:\Users\AAA\IdeaProjects\注解与反射\out\production\注解与反射;
C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.2\lib\idea_rt.jar
*/
System.out.println(System.getProperty("java.class.path"));
}
}
小结:自定义的类由系统加载器加载,系统JDK得内置类由根加载器加载。
获取运行时结构
package com.zzw.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class<?> aClass = Class.forName("com.zzw.reflection.User");
//获取全限定类名
String name = aClass.getName();
System.out.println(name);
//获取单类名
String simpleName = aClass.getSimpleName();
System.out.println(simpleName);
//获取public属性
Field[] fields = aClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
//获取全部属性
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//获取指定的属性
Field name1 = aClass.getDeclaredField("name");
System.out.println(name1);
//获取全部方法(包括父类的public方法)
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
//获取自己类中的方法
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("-" + declaredMethod);
}
//获取指定方法(需输入参数)
Method getName = aClass.getMethod("getName",null);
System.out.println(getName);
Method setName = aClass.getMethod("setName", String.class);
System.out.println(setName);
//获取public构造器
Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("public构造器 + " + constructor);
}
//获取全部构造器
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("全部构造器 + " + declaredConstructor);
}
//获取指定构造器
Constructor<?> constructor = aClass.getConstructor(String.class, int.class, int.class);
System.out.println("指定构造器 + " + constructor);
}
}
com.zzw.reflection.User
User
private java.lang.String com.zzw.reflection.User.name
private int com.zzw.reflection.User.age
private int com.zzw.reflection.User.is
private java.lang.String com.zzw.reflection.User.name
public java.lang.String com.zzw.reflection.User.toString()
public java.lang.String com.zzw.reflection.User.getName()
public void com.zzw.reflection.User.setName(java.lang.String)
public void com.zzw.reflection.User.setAge(int)
public int com.zzw.reflection.User.getIs()
public void com.zzw.reflection.User.setIs(int)
public int com.zzw.reflection.User.getAge()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
-public java.lang.String com.zzw.reflection.User.toString()
-public java.lang.String com.zzw.reflection.User.getName()
-public void com.zzw.reflection.User.setName(java.lang.String)
-public void com.zzw.reflection.User.setAge(int)
-public int com.zzw.reflection.User.getIs()
-public void com.zzw.reflection.User.setIs(int)
-public int com.zzw.reflection.User.getAge()
public java.lang.String com.zzw.reflection.User.getName()
public void com.zzw.reflection.User.setName(java.lang.String)
public构造器 + public com.zzw.reflection.User()
public构造器 + public com.zzw.reflection.User(java.lang.String,int,int)
全部构造器 + public com.zzw.reflection.User()
全部构造器 + public com.zzw.reflection.User(java.lang.String,int,int)
指定构造器 + public com.zzw.reflection.User(java.lang.String,int,int)
Process finished with exit code 0
动态创建对象
package com.zzw.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获取Class对象
Class c1 = Class.forName("com.zzw.reflection.User");
//调用无参构造
// User user1 = (User) c1.newInstance();
// System.out.println(user1);
//通过构造器创建对象
Constructor constructor = c1.getConstructor(String.class, int.class, int.class);
User user2 = (User) constructor.newInstance("漩涡鸣人", 07, 18);
System.out.println(user2);
//通过反射调用普通方法
User user3 = (User) c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke:激活
//(对象, 方法的值)
setName.invoke(user3, "海贼王");
System.out.println(user3.getName());
User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,需要关闭程序的检测程序,降低安全性
name.setAccessible(true);
name.set(user4, "柯南");
System.out.println(user4.getName());
}
}
invoke激活方法
setAccessible(true):设置私有属性的访问性
不同创建方式的效率
package com.zzw.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test10 {
public static void test01() {
User user = new User();
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
user.getName();
}
long end = System.currentTimeMillis();
System.out.println("正常时间:" + (end - start) + "ms");
}
public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getMethod("getName", null);
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long end = System.currentTimeMillis();
System.out.println("反射时间:" + (end - start) + "ms");
}
public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getMethod("getName", null);
getName.setAccessible(true);
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long end = System.currentTimeMillis();
System.out.println("反射关闭时间:" + (end - start) + "ms");
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test01();
test02();
test03();
}
}
正常时间:3ms
反射时间:3089ms
反射关闭时间:1439ms
参数化类型
package com.zzw.reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class Test11 {
public void test01(Map<String, User> map, List<User> list) {
System.out.println("test01");
}
public Map<String, User> test02() {
System.out.println("test02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method test01 = Test11.class.getMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = test01.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println(genericParameterType);
if (genericParameterType instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
System.out.println("-----------------------------");
Method test02 = Test11.class.getMethod("test02", null);
Type genericReturnType = test02.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
java.util.Map<java.lang.String, com.zzw.reflection.User>
class java.lang.String
class com.zzw.reflection.User
java.util.List<com.zzw.reflection.User>
class com.zzw.reflection.User
class java.lang.String
class com.zzw.reflection.User
获取注解信息
package com.zzw.reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class Test12 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
//获取类注解
Class c1 = Class.forName("com.zzw.reflection.Student02");
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取类注解信息
Tablezzw annotation = (Tablezzw) c1.getAnnotation(Tablezzw.class);
String value = annotation.value();
System.out.println(value);
Field name = c1.getDeclaredField("name");
Fieldzzw annotation1 = name.getAnnotation(Fieldzzw.class);
System.out.println(annotation1.columnName());
System.out.println(annotation1.type());
System.out.println(annotation1.length());
}
}
@Tablezzw("db_zzw")
class Student02 {
@Fieldzzw(columnName = "db_name", type = "varchar", length = 10)
private String name;
@Fieldzzw(columnName = "db_id", type = "int", length = 4)
private int id;
@Fieldzzw(columnName = "db_age", type = "int", length = 3)
private int age;
public Student02() {
}
public Student02(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student02{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tablezzw {
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldzzw {
String columnName();
String type();
int length();
}
@com.zzw.reflection.Tablezzw(value=db_zzw)
db_zzw
db_name
varchar
10