自定义注解
package com.badwei.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 自定义注解
public class Test03 {
//注解可以显式赋值,如果没有默认值,我们就必须给注解赋值
@MyAnnotation(name = "lxw")
public void test(){
}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
// 注解的参数:参数类型+参数名();
String name() default "";
int age() default 0;
int id() default -1;
String[] schools() default {"清华","北大"};
}
Java反射机制
1、反射
2、Class类
3、Class类的常用方法
4、获取Class类的实例
测试代码:
package com.badwei.reflection;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// 测试class类的创建方式有哪些
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println(person);
// 方式一:通过对象获得
Class c1 = person.getClass();
System.out.println("c1=>"+c1+" hashCode=" + c1.hashCode());
//方式二:通过forName获得
Class c2 = Class.forName("com.badwei.reflection.Student");
System.out.println("c2=>"+c2+" hashCode=" + c2.hashCode());
//方式三:通过类名.Class获得
Class<Student> c3 = Student.class;
System.out.println("c3=>"+c3+" hashCode=" + c3.hashCode());
//方式四:基本数据类型的包装类都有一个TYPE属性
Class<Integer> integerClass = Integer.TYPE;
System.out.println("integerClass=>"+integerClass);
// 获得父类类型
Class c5 = c1.getSuperclass();
System.out.println("c5=>"+c5+" hashCode=" + c5.hashCode());
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Person{
private String name;
}
class Student extends Person{
public Student(){
this.setName("学生");
}
}
class Teacher extends Person{
public Teacher(){
this.setName("老师");
}
}
5、那些类型可以有class对象
测试
package com.badwei.reflection;
import java.lang.annotation.ElementType;
// 所有类型的class
public class Test04 {
public static void main(String[] args) {
Class<Object> c1 = Object.class; //类
Class<Comparable> c2 = Comparable.class; //接口
Class<String[]> c3 = String[].class; //一位数组
Class<int[][]> c4 = int[][].class; //二维数组
Class<Override> c5 = Override.class; //注解
Class<ElementType> c6 = ElementType.class; //枚举
Class<Integer> c7 = Integer.class; //基本数据类型包装类
Class<Void> c8 = void.class; //void
Class<Class> c9 = Class.class; //Class
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
}
}
输出:
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.annotation.ElementType
class java.lang.Integer
void
class java.lang.Class
6、Java内存分析
7、类的加载
8、对象和类的创建内存分析
package com.badwei.reflection;
public class Test05 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
/*
1.加载到内存,会产生一个类对应的额Class对象
2.连接,链接结束后 m=0
3.初始化
<clinit>(){
System.out.println("A静态代码块初始化");
m = 300;
m = 100;
}
m=100
*/
}
}
class A{
static {
System.out.println("A静态代码块初始化");
m = 300;
}
static int m =100;
public A(){
System.out.println("A的无参构造器");
}
}
输出:
A静态代码块初始化
A的无参构造器
100
9、什么时候会发生类的初始化
10、分析类的初始化
package com.badwei.reflection;
// 测试类什么时候会初始化
public class Test06 {
static {
System.out.println("main加载");
}
public static void main(String[] args) throws ClassNotFoundException {
// 1.主动引用
// Son son = new Son();
/*
输出:
main加载
父类加载
子类加载
*/
//反射也会产生主动引用
// Class<?> aClass = Class.forName("com.badwei.reflection.Son");
/*
输出:
main加载
父类加载
子类加载
*/
//不会产生类的引用的方法 -子类调用父类的静态方法和变量,子类不会被加载
// System.out.println(Son.b);
/*
输出:
main加载
父类加载
2
*/
//只是一个数组空间,不会初始化
// Son[] sons = new Son[5];
/*
输出:
main加载
*/
// System.out.println(Son.M);
/*
输出:
main加载
1
*/
}
}
class Father{
static int b = 2;
static{
System.out.println("父类加载");
}
}
class Son extends Father{
static {
System.out.println("子类加载");
m = 300;
}
static int m = 100;
static final int M = 1;
}
输出:
main加载
父类加载
子类加载
11、类加载的作用
12、获取类加载器
package com.badwei.reflection;
public class Test7 {
public static void main(String[] args) throws ClassNotFoundException {
// 获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2
//获取系统类加载器的父类加载器-->拓展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent); //sun.misc.Launcher$ExtClassLoader@74a14482
//获取拓展类加载器的父类加载器-->根加载器(C/C++) 【java无法获取】
ClassLoader parent1 = parent.getParent();
System.out.println(parent1); //null
//测试当前类是哪个加载器加载的
ClassLoader classLoader = Class.forName("com.badwei.reflection.Test7").getClassLoader();
System.out.println(classLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2
//测试JDK内置的类是谁加载的 【是由根加载器加载的】
ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader1); //null
//如何获得系统类加载器可以加载的路径
String property = System.getProperty("java.class.path");
System.out.println(property);
/*
D:\Program Files\Java\jdk1.8.0_221\jre\lib\charsets.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\deploy.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\access-bridge-64.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\cldrdata.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\dnsns.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jaccess.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jfxrt.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\localedata.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\nashorn.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunec.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunjce_provider.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunmscapi.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunpkcs11.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\zipfs.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\javaws.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\jce.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\jfr.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\jfxswt.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\jsse.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\management-agent.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\plugin.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\resources.jar;
D:\Program Files\Java\jdk1.8.0_221\jre\lib\rt.jar;
D:\idea-study\注解和反射\target\classes;
C:\Users\12113\.m2\repository\org\projectlombok\lombok\1.18.20\lombok-1.18.20.jar;
D:\Program Files\JetBrains\IntelliJ IDEA 2021.1.1\lib\idea_rt.jar
*/
}
}
13、获取运行类的结构
package com.badwei.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<?> c1 = Class.forName("com.badwei.reflection.User");
//获得类的名字
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
//获得类的属性
Field[] fields = c1.getFields(); //只能找到public属性
fields = c1.getDeclaredFields(); //找到所有属性
for (Field field : fields) {
System.out.println(field);
}
//获得指定属性的值
Field name = c1.getDeclaredField("username");
System.out.println(name);
//获得类的方法
Method[] methods = c1.getMethods(); //获得本类及其父类的全部public方法
for (Method method : methods) {
System.out.println("getMethods=>"+method);
}
Method[] declaredMethods = c1.getDeclaredMethods(); //获得本类的所有方法
for (Method declaredMethod : declaredMethods) {
System.out.println("getDeclaredMethods=>"+declaredMethod);
}
//获得指定的方法
Method getUsername = c1.getMethod("getUsername", null);
Method setUsername = c1.getMethod("setUsername", String.class);
System.out.println(getUsername);
System.out.println(setUsername);
//获得指定的构造器
Constructor<?>[] constructors = c1.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("getConstructors=>"+constructor);
}
Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("getDeclaredConstructors=>"+declaredConstructor);
}
//获得指定的构造器
Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
System.out.println(declaredConstructor);
}
}
输出结果:
com.badwei.reflection.User
User
private java.lang.String com.badwei.reflection.User.username
private int com.badwei.reflection.User.id
private int com.badwei.reflection.User.age
private java.lang.String com.badwei.reflection.User.username
getMethods=>public boolean com.badwei.reflection.User.equals(java.lang.Object)
getMethods=>public java.lang.String com.badwei.reflection.User.toString()
getMethods=>public int com.badwei.reflection.User.hashCode()
getMethods=>public int com.badwei.reflection.User.getId()
getMethods=>public int com.badwei.reflection.User.getAge()
getMethods=>public void com.badwei.reflection.User.setId(int)
getMethods=>public void com.badwei.reflection.User.setAge(int)
getMethods=>public java.lang.String com.badwei.reflection.User.getUsername()
getMethods=>public void com.badwei.reflection.User.setUsername(java.lang.String)
getMethods=>public final void java.lang.Object.wait() throws java.lang.InterruptedException
getMethods=>public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
getMethods=>public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
getMethods=>public final native java.lang.Class java.lang.Object.getClass()
getMethods=>public final native void java.lang.Object.notify()
getMethods=>public final native void java.lang.Object.notifyAll()
getDeclaredMethods=>public boolean com.badwei.reflection.User.equals(java.lang.Object)
getDeclaredMethods=>public java.lang.String com.badwei.reflection.User.toString()
getDeclaredMethods=>public int com.badwei.reflection.User.hashCode()
getDeclaredMethods=>public int com.badwei.reflection.User.getId()
getDeclaredMethods=>public int com.badwei.reflection.User.getAge()
getDeclaredMethods=>protected boolean com.badwei.reflection.User.canEqual(java.lang.Object)
getDeclaredMethods=>public void com.badwei.reflection.User.setId(int)
getDeclaredMethods=>public void com.badwei.reflection.User.setAge(int)
getDeclaredMethods=>public java.lang.String com.badwei.reflection.User.getUsername()
getDeclaredMethods=>public void com.badwei.reflection.User.setUsername(java.lang.String)
public java.lang.String com.badwei.reflection.User.getUsername()
public void com.badwei.reflection.User.setUsername(java.lang.String)
getConstructors=>public com.badwei.reflection.User()
getConstructors=>public com.badwei.reflection.User(java.lang.String,int,int)
getDeclaredConstructors=>public com.badwei.reflection.User()
getDeclaredConstructors=>public com.badwei.reflection.User(java.lang.String,int,int)
public com.badwei.reflection.User(java.lang.String,int,int)
14、通过反射调用属性方法构造器
package com.badwei.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, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class<User> c1 = (Class<User>) Class.forName("com.badwei.reflection.User");
User user = c1.newInstance(); //本质调用了无参构造器,类要有一个访问权限足够的无参构造器
System.out.println(user);
//通过构造器创建对象
Constructor<User> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User lxw = declaredConstructor.newInstance("lxw", 1, 18);
System.out.println(lxw);
//通过反射调用普通方法
User user1 = c1.newInstance();
// invoke() 激活
//(对象, "方法的值")
Method setUsername = c1.getDeclaredMethod("setUsername", String.class);
setUsername.invoke(user1,"lxw_user1");
System.out.println(user1.getUsername());
//通过反射操作属性
User user2 = c1.newInstance();
Field username = c1.getDeclaredField("username");
//不能直接操作私有属性,通过setAccessible()可以取消安全监测
username.setAccessible(true); //取消安全监测
username.set(user2,"lxw_user2");
System.out.println(user2.getUsername());
}
}
15、分析性能问题
正常创建 > 关闭安全监测反射 > 普通反射
16、通过反射获取泛型信息
package com.badwei.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 method = Test11.class.getMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = method.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);
}
}
}
Method method1 = Test11.class.getMethod("test02", null);
Type genericReturnType = method1.getGenericReturnType();
System.out.println("#"+genericReturnType);
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
输出:
#java.util.Map<java.lang.String, com.badwei.reflection.User>
class java.lang.String
class com.badwei.reflection.User
#java.util.List<com.badwei.reflection.User>
class com.badwei.reflection.User
#java.util.Map<java.lang.String, com.badwei.reflection.User>
class java.lang.String
class com.badwei.reflection.User
17、获取注解信息
package com.badwei.reflection;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
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.badwei.reflection.Student2");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取注解value的值
TableLxw annotation = c1.getAnnotation(TableLxw.class);
String value = annotation.value();
System.out.println(value);
//活得类指定的注解
Field f = c1.getDeclaredField("id");
TableLxw annotation1 = f.getAnnotation(TableLxw.class);
System.out.println(annotation1.value());
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableLxw("lxwStudent2")
class Student2{
@TableLxw("lxwId")
private int id;
private int age;
private String name;
}
@Target({ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface TableLxw{ //自定义注解
String value();
}
输出:
@com.badwei.reflection.TableLxw(value=lxwStudent2)
lxwStudent2
lxwId
评论区