Java进阶07注解和反射
Java进阶07注解和反射

概述

package com.mingmao.annotationandreflection;
//什么是注解
public class Test01 {
@Override //重写的注解
public String toString() {
return super.toString();
}
}
注解
内置注解

package com.mingmao.annotationandreflection;
import java.util.ArrayList;
import java.util.List;
//什么是注解
public class Test01 {
@Override //重写的注解
public String toString() {
return super.toString();
}
@Deprecated //废弃注解
public void test01(){
System.out.println("@Deprecated");
}
@SuppressWarnings("all") //镇压警告,平时不建议镇压
public void test02(){
List list = new ArrayList();
}
public static void main(String[] args) {
Test01 test01 = new Test01();
test01.test01();
}
}
元注解

package com.mingmao.annotationandreflection;
import java.lang.annotation.*;
//测试元注解
@MyAnnotation
public class Test02 {
@MyAnnotation
public void test02(){
}
}
//定义注解
//Target约束注解可以放在哪些地方
//这个注解可以放在方法上,也可以放在类上
@Target(value= {ElementType.METHOD,ElementType.TYPE})
//Retention表示我们的注解在什么时候才有效,runtime所有时间有效
//runtime>class>sources
@Retention(value = RetentionPolicy.RUNTIME)
//Documented表示是否将注解生成在javadoc中
@Documented
//Inherited子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
}
自定义注解

package com.mingmao.annotationandreflection;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//自定义注解
public class Test03 {
@MyAnnotation2(name="mm",age = 18,id = 001,schools = {"清华","北大"})
public void test01(){}
@MyAnnotation3("mingmao")
public void test02(){}
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
//注解的参数:参数类型+参数名();
String name() default ""; //默认值为空,如果没有默认值,必须显式赋值
int age() default 0;
int id() default -1;//默认值-1,代表不存在
String[] schools() default {};
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
String value() default "";//只有一个属性建议用value命名
}
反射
反射概述


动态语言举例:js
function f() {
var x="var a=3;var b=5;alert(a+b)";
eval(x);
}

获得反射对象




package com.mingmao.annotationandreflection.reflection;
//什么叫反射
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取类的class对象,
// 一个类在内存中只有一个class对象,一个类被加载后,类的整个结构都会被封装在class对象中
Class aClass = Class.forName("com.mingmao.annotationandreflection.reflection.User");
System.out.println(aClass);//class com.mingmao.annotationandreflection.reflection.User
}
}
//实体类
class User{
private String name;
private int age;
private int id;
public User() {
}
public User(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
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 getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}
得到class类的几种方式



package com.mingmao.annotationandreflection.reflection;
//测试class类的创建方式有哪些
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException {
Person person=new Student();
System.out.println("这个人是"+person.name);
//方式一:通过对象获得
Class aClass = person.getClass();
System.out.println(aClass.hashCode());//1956725890
//方式二:forname获得
Class aClass1 = Class.forName("com.mingmao.annotationandreflection.reflection.Student");
System.out.println(aClass1.hashCode());//1956725890
//方式三:通过类名.class获得
Class studentClass = Student.class;
System.out.println(studentClass.hashCode());//1956725890
//方式四:基本内置类型的包装类都有一个Type属性
Class type = Integer.TYPE;
System.out.println(type);//int
//获得父类类型
Class superclass = aClass.getSuperclass();
System.out.println(superclass);//class com.mingmao.annotationandreflection.reflection.Person
}
}
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="老师";
}
}
所有类型的class对象

package com.mingmao.annotationandreflection.reflection;
import java.lang.annotation.ElementType;
//所有类型的class
public class Test04 {
public static void main(String[] args) {
Class objectClass = Object.class;//类
Class comparableClass = Comparable.class;//接口
Class aClass = String[].class;//数组
Class aClass1 = int[][].class;//二维数组
Class overrideClass = Override.class;//注解
Class elementTypeClass = ElementType.class;//枚举
Class integerClass = Integer.class;//基本数据类型
Class voidClass = void.class;//空类型
Class classClass = Class.class;//Class类
System.out.println(objectClass);//class java.lang.Object
System.out.println(comparableClass);//interface java.lang.Comparable
System.out.println(aClass);//class [Ljava.lang.String;
System.out.println(aClass1);//class [[I
System.out.println(overrideClass);//interface java.lang.Override
System.out.println(elementTypeClass);//class java.lang.annotation.ElementType
System.out.println(integerClass);//class java.lang.Integer
System.out.println(voidClass);//void
System.out.println(classClass);//class java.lang.Class
}
}
类加载内存分析



package com.mingmao.annotationandreflection.reflection;
public class Test05 {
public static void main(String[] args) {
A a = new A();
System.out.println(a.m);
/*
A类静态代码块初始化
A类的无参构造初始化
100
*/
}
}
class A{
static {
System.out.println("A类静态代码块初始化");
m=300;
}
static int m=100;
public A() {
System.out.println("A类的无参构造初始化");
}
}


package com.mingmao.annotationandreflection.reflection;
//测试类什么时候会初始化
public class Test06 {
static {
System.out.println("main类被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
//1.主动引用
// Son son = new Son();
/*
main类被加载
父类被加载
子类被加载
*/
//2.反射也会产生主动引用
// Class<?> aClass = Class.forName("com.mingmao.annotationandreflection.reflection.Son");
/*
main类被加载
父类被加载
子类被加载
*/
//不会产生类的引用的方法
//1.子类调用父类的静态变量,子类不会被加载
// System.out.println(Son.b);
/*
main类被加载
父类被加载
2
*/
//2.调用的是类的数组,则子类和父类均不会被加载
//Son[] sons = new Son[5];
/*
main类被加载
*/
//3.调用常量池的常量,不会引起子类和父类的初始化
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;
}


package com.mingmao.annotationandreflection.reflection;
public class Test07 {
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++)
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);//null
//测试当前类是哪个加载器加载的
ClassLoader classLoader = Class.forName("com.mingmao.annotationandreflection.reflection.Test07").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);
/*
C:\Program Files\Java\jdk1.8.0_301\jre\lib\charsets.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\deploy.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\access-bridge-64.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\cldrdata.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\dnsns.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jaccess.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jfxrt.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\localedata.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\nashorn.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunec.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunjce_provider.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunmscapi.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunpkcs11.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\zipfs.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\javaws.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\jce.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfr.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfxswt.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\jsse.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\management-agent.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\plugin.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\resources.jar;
C:\Program Files\Java\jdk1.8.0_301\jre\lib\rt.jar;
D:\file\javatest\JavaSE\java进阶\out\production\java进阶;
D:\file\javatest\JavaSE\java进阶\src\lib\commons-io-2.11.0.jar;
D:\ruanjian\idealIU\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar
*/
//双亲委派机制
//java.lang.String 自己写一个包如果和原有的包冲突,自己写的包无效。
}
}
创建运行时类的对象

package com.mingmao.annotationandreflection.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.mingmao.annotationandreflection.reflection.User");
//获得类的名字
System.out.println(aClass.getName());//com.mingmao.annotationandreflection.reflection.User
System.out.println(aClass.getSimpleName());//User
//获得类的属性
Field[] fields = aClass.getDeclaredFields();//获得所有属性
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i]);
}
/*
private java.lang.String com.mingmao.annotationandreflection.reflection.User.name
private int com.mingmao.annotationandreflection.reflection.User.age
private int com.mingmao.annotationandreflection.reflection.User.id
*/
Field name = aClass.getDeclaredField("name");//获得指定属性的值
System.out.println(name);//private java.lang.String com.mingmao.annotationandreflection.reflection.User.name
//获得类的方法
Method[] declaredMethods = aClass.getDeclaredMethods();//获得本类的所有方法
for (int i = 0; i < declaredMethods.length; i++) {
System.out.println(declaredMethods[i]);
}
System.out.println("==================================================");
/*
public java.lang.String com.mingmao.annotationandreflection.reflection.User.toString()
public java.lang.String com.mingmao.annotationandreflection.reflection.User.getName()
public int com.mingmao.annotationandreflection.reflection.User.getId()
public void com.mingmao.annotationandreflection.reflection.User.setName(java.lang.String)
public void com.mingmao.annotationandreflection.reflection.User.setAge(int)
public void com.mingmao.annotationandreflection.reflection.User.setId(int)
public int com.mingmao.annotationandreflection.reflection.User.getAge()
*/
Method[] methods = aClass.getMethods();//获得本类及其父类的全部public方法
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i]);
}
/*
public java.lang.String com.mingmao.annotationandreflection.reflection.User.toString()
public java.lang.String com.mingmao.annotationandreflection.reflection.User.getName()
public int com.mingmao.annotationandreflection.reflection.User.getId()
public void com.mingmao.annotationandreflection.reflection.User.setName(java.lang.String)
public int com.mingmao.annotationandreflection.reflection.User.getAge()
public void com.mingmao.annotationandreflection.reflection.User.setId(int)
public void com.mingmao.annotationandreflection.reflection.User.setAge(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()
*/
Method getName = aClass.getMethod("getName", null);//获得指定方法
System.out.println(getName);//public java.lang.String com.mingmao.annotationandreflection.reflection.User.getName()
Method setName = aClass.getDeclaredMethod("setName", String.class);
System.out.println(setName);//public void com.mingmao.annotationandreflection.reflection.User.setName(java.lang.String)
//获得全部的构造器
System.out.println("=======================================================");
Constructor<?>[] constructors = aClass.getConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println(constructors[i]);
}
/*
public com.mingmao.annotationandreflection.reflection.User()
public com.mingmao.annotationandreflection.reflection.User(java.lang.String,int,int)
*/
System.out.println("==========================================================");
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
for (int i = 0; i < declaredConstructors.length; i++) {
System.out.println(declaredConstructors[i]);
}
/*
public com.mingmao.annotationandreflection.reflection.User()
public com.mingmao.annotationandreflection.reflection.User(java.lang.String,int,int)
*/
Constructor<?> constructor = aClass.getConstructor(String.class, int.class, int.class);//获得指定构造器
System.out.println(constructor);//public com.mingmao.annotationandreflection.reflection.User(java.lang.String,int,int)
}
}
动态创建对象执行方法




package com.mingmao.annotationandreflection.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<?> aClass = Class.forName("com.mingmao.annotationandreflection.reflection.User");
//创建对象方式一,构造对象
User user = (User)aClass.newInstance();//本质上是调用了无参构造器
System.out.println(user);//User{name='null', age=0, id=0}
//创建对象方式二:通过构造器创建对象
Constructor<?> constructor = aClass.getConstructor(String.class, int.class, int.class);
User user1 = (User) constructor.newInstance("mm", 001, 18);
System.out.println(user1);//User{name='mm', age=1, id=18}
//用过反射调用普通方法
Method setName = aClass.getMethod("setName", String.class);
setName.invoke(user,"mm");//invoke 激活,对象,参数
System.out.println(user.getName());//mm
//通过反射操作属性
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);//不能直接操作私有属性,需要先关闭程序的安全检测
name.set(user,"mingmao");
System.out.println(user.getName());//mingmao
}
}
性能对比分析
package com.mingmao.annotationandreflection.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//分析性能问题
public class Test10 {
//普通方式调用
public void test01(){
User user = new User();
long startTime=System.currentTimeMillis();
for (int i = 0; i < 10_0000_0000; i++) {
user.getName();
}
long endTime=System.currentTimeMillis();
System.out.println("普通方式执行10亿次时间:"+(endTime-startTime));
}
//反射方式调用
public void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class<? extends User> aClass = user.getClass();
Method getName = aClass.getDeclaredMethod("getName",null);
long startTime=System.currentTimeMillis();
for (int i = 0; i < 10_0000_0000; i++) {
User user1 = (User) getName.invoke(user,null);
}
long endTime=System.currentTimeMillis();
System.out.println("反射方式执行10亿次时间:"+(endTime-startTime));
}
//反射方式调用,关闭检测
public void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class<? extends User> aClass = user.getClass();
Method getName = aClass.getDeclaredMethod("getName",null);
getName.setAccessible(true);
long startTime=System.currentTimeMillis();
for (int i = 0; i < 10_0000_0000; i++) {
User user1 = (User) getName.invoke(user,null);
}
long endTime=System.currentTimeMillis();
System.out.println("反射方式(关闭检测)执行10亿次时间:"+(endTime-startTime));
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Test10 test10 = new Test10();
test10.test01();//普通方式执行10亿次时间:4
test10.test02();//反射方式执行10亿次时间:2110
test10.test03();//反射方式(关闭检测)执行10亿次时间:1486
}
}
获取泛型信息

package com.mingmao.annotationandreflection.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("===================================================");
/*
java.util.Map<java.lang.String, com.mingmao.annotationandreflection.reflection.User>
class java.lang.String
class com.mingmao.annotationandreflection.reflection.User
java.util.List<com.mingmao.annotationandreflection.reflection.User>
class com.mingmao.annotationandreflection.reflection.User
*/
//获得返回值泛型信息
Method test02 = Test11.class.getMethod("test02", null);
Type genericReturnType = test02.getGenericReturnType();//获得返回值泛型信息
if(genericReturnType instanceof ParameterizedType){
System.out.println(genericReturnType);
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
/*
java.util.Map<java.lang.String, com.mingmao.annotationandreflection.reflection.User>
class java.lang.String
class com.mingmao.annotationandreflection.reflection.User
*/
}
}
获得注解信息


package com.mingmao.annotationandreflection.reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
//练习反射操作注解
public class Test12 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class<?> aClass = Class.forName("com.mingmao.annotationandreflection.reflection.Student2");
//通过反射获得注解
Annotation[] annotations = aClass.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//@com.mingmao.annotationandreflection.reflection.MyTable(value=db_student)
//获得注解的value值
MyTable myTable = (MyTable) aClass.getAnnotation(MyTable.class);
System.out.println(myTable.value());//db_student
//获得类指定的注解
Field name = aClass.getDeclaredField("name");
MyField myField = (MyField) name.getAnnotation(MyField.class);
System.out.println(myField.colNme());//db_name
System.out.println(myField.type());//varchar
System.out.println(myField.length());//3
}
}
@MyTable("db_student")
class Student2{
@MyField(colNme = "db_id",type = "int",length = 10)
private int id;
@MyField(colNme = "db_age",type = "int",length = 10)
private int age;
@MyField(colNme = "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 MyTable{
String value() default "";
}
//属性的注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyField{
String colNme();
String type();
int length();
}

浙公网安备 33010602011771号