四个元注解
package net.yscxy.annoction;
import java.lang.annotation.*;
/**
* @Author WangFuKun
* @create 2020/12/4 20:20
*/
//测试元注解
public class Test02 {
@MyAnotation
public void test() {
}
}
//定义一个注解
//Target表示我们的注解可以用在哪些地方
//Retention表示我们的注解在什么时候还有效runtime>class>source
//Documented表示是否将我们的注解生成在javadoc中
//Inherited子类可以继承父类
@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented()
@Inherited()
@interface MyAnotation {
}
Target 表示我们的注解可以用在哪些地方
Retention 表示我们的注解在什么时候还有效 runtime>class>source
Documented 表示是否将我们的注解生成在 javadoc 中
Inherited 子类可以继承父类
如何自定义注解
package net.yscxy.annoction;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Author WangFuKun
* @create 2020/12/4 21:30
*/
//自定义注解
public class Test03 {
@Test
@MyAnnotation2(name = "wfk", age = 10)
public void test() {
}
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
//注解的参数:参数类型+参数名();
String name() default "";
int age();
int id() default -1;//如果默认值为-1,代表不存在,如果找不到就返回-1
String[] schools() default {"清华大学", };
}
反射机制
静态语言 VS 动态语言
Java Reflection
获取 Class 类的实例的几种方案
package net.yscxy.reflection;
/**
* @Author 野生程序员 http://yscxy.net/
* @create 2020/12/5 10:29
*/
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是->" + person.name);
//方式一:通过对象获得
Class c1 = person.getClass();
System.out.println(c1);
//方式二:forname获得
Class c2 = Class.forName("net.yscxy.reflection.Student");
System.out.println(c2);
//方式三:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3);
//方式四:基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4);
//获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
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 = "老师";
}
}
代码二
package net.yscxy.reflection;
import java.lang.annotation.ElementType;
/**
* @Author 野生程序员 http://yscxy.net/
* @create 2020/12/5 10:46
*/
//所有类的class
public class Test04 {
public static void main(String[] args) {
Class c1 = Object.class;//类
Class c2 = Comparable.class;//接口
Class c3 = String[].class;//一维数组
Class c4 = int[][].class;//二维数组
Class c5 = Override.class;//注解
Class c6 = ElementType.class;//枚举
Class c7 = Integer.class;//基本数据类型
Class c8 = void.class;//void
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);
}
}
什么时候会发生类的初始化
package net.yscxy.reflection;
/**
* @Author 野生程序员 http://yscxy.net/
* @create 2020/12/5 11:10
*/
public class Test06 {
static {
System.out.println("main类被加载...");
}
public static void main(String[] args) throws ClassNotFoundException {
//1.主动引用
//Son son = new Son();
//反射也会产生主动引用引用
//Class.forName("net.yscxy.reflection.Son");
//不会产生类的引用的方法
//System.out.println(Son.b);
//Son[] arr = 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("子类被加载...");
}
static int m = 100;
static final int M = 1;
}
类加载器的作用
获取类的方法、字段、构造器、等等
package net.yscxy.reflection;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @Author 野生程序员 http://yscxy.net/
* @create 2020/12/5 15:49
*/
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("net.yscxy.reflection.User");
//获得类的名字
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
//获得类的属性
Field[] fields = c1.getFields();//只能找到public属性
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i]);
}
Field name = c1.getDeclaredField("name");
System.out.println(name);
//获得类的方法
System.out.println("=======================获得类的方法=========================");
Arrays.asList(c1.getMethods()).forEach(System.out::println);//获得本类以及父类的全部public方法
System.out.println("=======================获得本类的所有方法=========================");
Arrays.asList(c1.getDeclaredMethods()).forEach(System.out::println);//获得本类的所有方法
//获得指定方法
System.out.println("获得指定方法");
Method getName = c1.getMethod("getName", null);
Method getAge = c1.getMethod("getAge", null);
System.out.println(getName);
System.out.println(getAge);
System.out.println("获得指定的构造器");
Constructor[] constructors = c1.getConstructors();
Arrays.asList(constructors).forEach(System.out::println);
System.out.println("+++++++++++");
Arrays.asList(c1.getDeclaredConstructors()).forEach(System.out::println);
System.out.println("获得指定的构造器");
Constructor declaredConstructor = c1.getDeclaredConstructor(int.class, String.class, int.class);
System.out.println("指定:" + declaredConstructor);
}
}
通过反射动态创建对象
package net.yscxy.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @Author 野生程序员 http://yscxy.net/
* @create 2020/12/6 8:43
*/
//通过反射动态创建对象
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class<?> c1 = Class.forName("net.yscxy.reflection.User");
//构造对象
User user = (User) c1.newInstance();
System.out.println(user);
//通过构造器创建对象
Constructor<?> declaredConstructor = c1.getDeclaredConstructor(int.class, String.class, int.class);
User user13 = (User) declaredConstructor.newInstance(1, "测试", 1);
System.out.println(user13);
//通过反射获取一个方法,invoke激活的意思
User user3 = (User) c1.newInstance();
Method setName = c1.getDeclaredMethod("setName", String.class);
setName.invoke(user3, "野生程序员");
System.out.println(user3);
//通过反射操作属性
User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
//设置属性是否可以被访问,也就是取消他的安全监测,不能直接访问私有属性,只有关掉之后才能访问
name.setAccessible(true);
name.set(user4, "野生程序员2");
System.out.println(user4);
}
}
三种方式的额性能检测
package net.yscxy.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @Author 野生程序员 http://yscxy.net/
* @create 2020/12/7 16:07
*/
//分析反射性能问题
public class Test10 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test01();
test02();
test3();
}
//普通方式调用
public static void test01() {
User user = new User();
long starTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方式耗费时间->" + (endTime - starTime));
}
//反射方式调用
public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long starTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方式耗费时间->" + (endTime - starTime));
}
//反射方式调用 并且关闭安全检测
public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long starTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射并且关闭安全检查方式耗费时间->" + (endTime - starTime));
}
}
运行结果
普通方式耗费时间->5
反射方式耗费时间->4928
反射并且关闭安全检查方式耗费时间->2171
通过反射操作泛型
package net.yscxy.reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
/**
* @Author 野生程序员 http://yscxy.net/
* @create 2020/12/7 16:24
*/
//通过反射获取泛型
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[] genericExceptionTypes = method.getGenericParameterTypes();
for (Type ge : genericExceptionTypes) {
System.out.println(ge);
//instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例
if (ge instanceof ParameterizedType) {
System.out.println("开始打印...");
Type[] actualTypeArguments = ((ParameterizedType) ge).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
System.out.println("获取返回值的泛型的参数类型...");
method = Test11.class.getMethod("test02", null);
Type genericReturnType = method.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, net.yscxy.reflection.User>
开始打印...
class java.lang.String
class net.yscxy.reflection.User
java.util.List<net.yscxy.reflection.User>
开始打印...
class net.yscxy.reflection.User
获取返回值的泛型的参数类型...
java.util.Map<java.lang.String, net.yscxy.reflection.User>
class java.lang.String
class net.yscxy.reflection.User
反射操作注解
了解一下什么叫 ORM
package net.yscxy.reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
/**
* @Author 野生程序员 http://yscxy.net/
* @create 2020/12/7 16:59
*/
public class Test12 {
public static void main(String[] args) throws NoSuchFieldException {
Class c1 = Student2.class;
//通过反射获取注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation a : annotations) {
System.out.println(a);
}
//获取注解的value的值
TableY tableY = (TableY) c1.getAnnotation(TableY.class);
System.out.println(tableY.value());
//获得类指定的注解
Field f = c1.getDeclaredField("name");
FiledY annotation = f.getAnnotation(FiledY.class);
System.out.println(annotation.columnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
//数据
@TableY("du_student")
class Student2 {
@FiledY(columnName = "db_id", type = "int", length = 10)
private int id;
@FiledY(columnName = "db_age", type = "int", length = 10)
private int age;
@FiledY(columnName = "db_name", type = "varchar", length = 3)
private String name;
public Student2() {
}
public Student2(int id, int age, String name) {
this.id = id;
this.age = age;
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;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student2{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
//类名注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface TableY {
String value();
}
//属性的注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface FiledY {
String columnName();
String type();
int length();
}
运行结果
@net.yscxy.reflection.TableY(value=du_student)
du_student
db_name
carchar
3
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于