public class Test {
@MyAnnotation
public void test() {
}
}
/**
* Target:注解的使用范围
* Retention:注解的有效范围,runtime>class>sources
* Documented:注解是否生成在JavaDoc中
* Inherited:子类可以继承父类中的该注解
*/
@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation {
}
public class Test2 {
/**
* 注解可以显示赋值,如果没有默认值,我们就必须给注解赋值
*/
@MyAnnotation2(name = "young")
public void test() {
}
@MyAnnotation3("young")
public void test2() {
}
}
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
/**
* 注解的参数:参数类型+参数名();
*/
String name() default "";
int age() default 0;
/**
* 如果默认值为-1,代表不存在
*/
int id() default -1;
String[] schools() default {"肇庆学院","清华大学"};
}
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
String value();
}
public class Test3 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取类的class对象
Class c1 = Class.forName("com.reflection.Test3");
Class c2 = Class.forName("com.reflection.Test3");
Class c3 = Class.forName("com.reflection.Test3");
Class c4 = Class.forName("com.reflection.Test3");
System.out.println(c1);
//一个类在内存中只有一个class对象
//一个类被加载后,类的整个结构都会封装在Class对象中
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
}
}
//实体类:pojo、entity
class User{
private String name;
private int id;
private int age;
public User() {
}
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", 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;
}
}
结果:
class com.reflection.Test3
1956725890
1956725890
1956725890
Process finished with exit code 0
在Object类中定义了以下的方法,此方法将被所有子类继承
public final Class getClass()
以上方法的返回值的类型是一个Class类,此类是Java反射的源头,实际上所谓反射从程序的运行结果来看也很好理解,即:可以通过对象反射求出类的名称。
对象照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE都为其保留一个不变的Class类型的对象。一个Class对象包含了特定某个结构(class/interface/enum/annotation/primitive type/void/[])的有关信息。
若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高。
Class clazz = Person.class;
已知某个类的实例,调用该实例的getClass()方法获取Class对象
Class clazz = person.getClass();
已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
Class clazz = Class.forName("demo01.Student");
内置基本数据类型可以直接用类名.Type
还可以利用ClassLoader
public class Test4 {
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.hashCode());
//方式二:forname获得
Class c2 = Class.forName("com.reflection.Student");
System.out.println(c2.hashCode());
//方式三:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3.hashCode());
//方式四:基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4);
//获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public 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 = "老师";
}
}
结果:
这个人是:学生
356573597
356573597
356573597
int
class com.reflection.Person
Process finished with exit code 0
public class Test5 {
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;
//void
Class c8 = void.class;
//Class
Class c9 = 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
int[] a = new int[10];
int[] b = new int[100];
System.out.println(a.getClass().hashCode());
System.out.println(b.getClass().hashCode());
}
}
结果:
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
356573597
356573597
Process finished with exit code 0
public class Test6 {
public static void main(String[] args) {
A a = new A();
System.out.println(a.m);
}
}
class A {
static {
System.out.println("A类静态代码块初始化");
m = 300;
}
static int m = 100;
public A() {
System.out.println("A类的无参构造初始化");
}
}
结果:
A类静态代码块初始化
A类的无参构造初始化
100
public class Test7 {
static {
System.out.println("main类被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
//主动引用
Son son = new Son();
//反射会产生主动引用
Class.forName("com.reflection.Son");
//不会产生类的引用的方法
//System.out.println(Son.b);
Son[] array = 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 = 300;
}
static int m=100;
static final int M = 1;
}
结果:
main类被加载
父类被加载
子类被加载
1
Process finished with exit code 0
类加载器作用时把类(class)装载进内存的。JVM规范定义了如下类型的类的加载器。
public class Test8 {
public static void main(String[] args) throws ClassNotFoundException {
//获取系统类的加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//获取系统类加载器的父类加载器-->扩展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
//获取扩展类加载器的父类加载器-->根加载器(C++编写)
ClassLoader grandParent = parent.getParent();
System.out.println(grandParent);
//测试当前类是哪个加载器加载的
ClassLoader classLoader = Class.forName("com.reflection.Test8").getClassLoader();
System.out.println(classLoader);
//测试JDK内置类是哪个加载器加载的
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
//如何获得系统类加载器可以加载的路径
System.out.println(System.getProperty("java.class.path"));
}
}
结果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1540e19d
null
sun.misc.Launcher$AppClassLoader@18b4aac2
null
E:\Java\jdk1.8.0_131\jre\lib\charsets.jar;E:\Java\jdk1.8.0_131\jre\lib\deploy.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;E:\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;E:\Java\jdk1.8.0_131\jre\lib\javaws.jar;E:\Java\jdk1.8.0_131\jre\lib\jce.jar;E:\Java\jdk1.8.0_131\jre\lib\jfr.jar;E:\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;E:\Java\jdk1.8.0_131\jre\lib\jsse.jar;E:\Java\jdk1.8.0_131\jre\lib\management-agent.jar;E:\Java\jdk1.8.0_131\jre\lib\plugin.jar;E:\Java\jdk1.8.0_131\jre\lib\resources.jar;E:\Java\jdk1.8.0_131\jre\lib\rt.jar;E:\IdeaProjects\JavaProject\out\production\Annotation;E:\IntelliJ IDEA 2020.1.1\lib\idea_rt.jar
Process finished with exit code 0
通过反射获取运行时类的完整结构Field、Method、Constructor、Superclass、Interface、Annotation
public class Test9 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("com.reflection.User");
//获得类的名字
//获得包名+类名
System.out.println(c1.getName());
//获得类名
System.out.println(c1.getSimpleName());
//获得类的属性
//public属性
Field[] fields = c1.getFields();
for (Field field : fields) {
System.out.println(field);
}
//全部属性
fields = c1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
//获得指定属性的值
Field name = c1.getDeclaredField("name");
System.out.println(name);
//获得类的方法
//获得本类及其父类的全部public方法
Method[] methods = c1.getMethods();
//获得本类的所有方法
Method[] declaredMethods = c1.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
for (Method method : declaredMethods) {
System.out.println(declaredMethods);
}
//获得指定方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
//获得指定的构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
}
}
结果:
com.reflection.User
User
private java.lang.String com.reflection.User.name
private int com.reflection.User.id
private int com.reflection.User.age
private java.lang.String com.reflection.User.name
public java.lang.String com.reflection.User.toString()
public java.lang.String com.reflection.User.getName()
public int com.reflection.User.getId()
public void com.reflection.User.setName(java.lang.String)
public int com.reflection.User.getAge()
public void com.reflection.User.setAge(int)
public void com.reflection.User.setId(int)
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()
[Ljava.lang.reflect.Method;@14ae5a5
[Ljava.lang.reflect.Method;@14ae5a5
[Ljava.lang.reflect.Method;@14ae5a5
[Ljava.lang.reflect.Method;@14ae5a5
[Ljava.lang.reflect.Method;@14ae5a5
[Ljava.lang.reflect.Method;@14ae5a5
[Ljava.lang.reflect.Method;@14ae5a5
public java.lang.String com.reflection.User.getName()
public void com.reflection.User.setName(java.lang.String)
public com.reflection.User()
public com.reflection.User(java.lang.String,int,int)
public com.reflection.User()
public com.reflection.User(java.lang.String,int,int)
Process finished with exit code 0
只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,才可以实例化操作。
调用指定的方法
通过反射,调用类中的方法,通过Method类完成。
Object invoke(Object obj,Object ... args)
setAccessible
public class Test10 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获得Class对象
Class c1 = Class.forName("com.reflection.User");
//构造一个对象,本质上是调用了类的无参构造方法
User user = (User) c1.newInstance();
System.out.println(user);
//通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User user2 = (User) constructor.newInstance("young", 1, 15);
System.out.println(user2);
//通过反射调用普通方法
User user3 = (User) c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke:激活
setName.invoke(user3,"young");
System.out.println(user3.getName());
//通过反射操作属性
User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,关闭程序的安全检测,属性或者方法的setAccessible(true)
name.setAccessible(true);
name.set(user4,"young2");
System.out.println(user4.getName());
}
}
结果:
User{name='null', id=0, age=0}
User{name='young', id=1, age=15}
young
young2
public class Test11 {
//普通方式调用
public static void test1() {
User user = new User();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方法执行10亿次"+(endTime-startTime)+"ms");
}
//反射方式调用
public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方法执行10亿次"+(endTime-startTime)+"ms");
}
//反射方式调用 关闭检测
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 startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方法关闭检测执行10亿次"+(endTime-startTime)+"ms");
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test1();
test2();
test3();
}
}
结果:
普通方法执行10亿次4ms
反射方法执行10亿次2821ms
反射方法关闭检测执行10亿次1482ms
Process finished with exit code 0
public class Test12 {
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 = Test12.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 = Test12.class.getMethod("test02", null);
Type genericReturnType = method.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.reflection.User>
class java.lang.String
class com.reflection.User
#java.util.List<com.reflection.User>
class com.reflection.User
class java.lang.String
class com.reflection.User
Process finished with exit code 0