一、注解#
1. 初识注解#
package com.onlineframework;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("all")
public class annoTest {
@Override
public String toString() {
return super.toString();
}
@Deprecated
public static void dep(){
System.out.println("dep");
}
public static void test02(){
List list = new ArrayList();
}
public static void main(String[] args) {
dep();
test02();
}
}
2. 元注解#
package com.onlineframework;
import java.lang.annotation.*;
@MyAnnotation
public class AnnoTest02 {
@MyAnnotation
public void test(){
}
}
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
@Inherited
@interface MyAnnotation{ //@interface自动继承了java.lang.annotation.Annotation接口
}
3. 自定义注解,设置其默认值#
package com.onlineframework;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class AnnoTest03 {
@MyAnnotation2()
@MyAnnotation3("OK")
public void test(){
}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
//定义参数:参数类型 + 参数名
String name() default "";
int age() default 0;
int id() default -1;
String[] schools() default {};
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
String[] value();
}
二、反射#
1. 什么是反射#
package com.onlineframework;
//什么是反射
public class ReflectionTest01 {
public static void main(String[] args) throws ClassNotFoundException {
//一个类被加载后,类的整个结构都会被封装在Class对象中
//三种获得Class对象的方法
Class c1 = Class.forName("com.onlineframework.User");
Class c2 = new User().getClass();
Class c3 = User.class;
System.out.println(c1.hashCode() == c2.hashCode() && c2.hashCode() == c3.hashCode()); //一个类在内存中只有一个Class对象
}
}
class User{
private String name;
private int id;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
public User(){}
public User(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;
}
}
2. 获得父类对象#
package com.onlineframework;
public class ReflectionTest02 {
public static void main(String[] args) throws ClassNotFoundException {
Person p = new Student();
Class c1 = p.getClass();
Class c2 = Class.forName("com.onlineframework.Person");
Class c3 = Person.class;
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
//内置包装类都有一个TYPE属性
Class<Integer> c4 = Integer.TYPE;
System.out.println(c4);
//获得父类对象
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public int age;
}
class Student extends Person{
public Student(){
this.name = "stu";
}
}
class Teacher extends Person{
public Teacher(){
this.name = "teach";
}
}
3. 各种类型的Class对象#
package com.onlineframework;
import java.lang.annotation.ElementType;
public class ReflectionTest04 {
public static void main(String[] args) {
Class objectClass = Object.class; //类
Class comparableClass = Comparable.class; //接口
Class strArrayClass = String[].class;//一维数组
Class intArrayClass = int[][].class;//二维数组
Class overrideClass = Override.class;//注解
Class elementTypeClass = ElementType.class; //枚举
Class integerClass = Integer.class;//基本数据类型
Class voidClass = void.class;//void
Class classClass = Class.class;
System.out.println(objectClass);
System.out.println(comparableClass);
System.out.println(strArrayClass);
System.out.println(intArrayClass);
System.out.println(overrideClass);
System.out.println(elementTypeClass);
System.out.println(integerClass);
System.out.println(voidClass);
System.out.println(classClass);
int [] a = new int[10];
int [] b = new int[20];
System.out.println(a.getClass().hashCode()); //只要类型与维度一样,就是同一个Class
System.out.println(b.getClass().hashCode());
System.out.println(a.getClass().hashCode() == b.getClass().hashCode()); //true
}
}
4. 类加载的过程、Class对象加载的时机#
package com.onlineframework;
public class ReflectionTest05 {
public static void main(String[] args) {
System.out.println("new之前");
System.out.println(A.m);
System.out.println("new之前");
A a = new A();
System.out.println(A.m);
/*
* 1. 加载,会产生一个类对应的Class对象
* 2. 链接,链接结束后 m = 0
* 3. 初始化,
* <clinit>(){
* m=300;
* System.out.println("静态代码块");
* m=100;
* }
* 此时 m = 100
* */
}
}
class A{
static {
m=300;
System.out.println("静态代码块");
}
static int m = 100;
public A(){
System.out.println("无参构造");
}
}
5. 类初始化的时机#
package com.onlineframework;
//类什么时候初始化?
public class ReflectionTest06 {
static {
System.out.println("Main init");
}
public static void main(String[] args) throws ClassNotFoundException {
//Son son = new Son();
/*
Main init
Father init
Son init
*/
//Class.forName("com.onlineframework.Son");
/*
Main init
Father init
Son init
*/
//System.out.println(Son.b); //Son类不会加载
/*
Main init
Father init
2
*/
//Son[] array = new Son[5]; //不会引起任何初始化
/*Main init*/
System.out.println(Son.M); //常量在链接阶段就被赋值,不引起任何初始化
/*Main init*/
}
}
class Father {
static {
System.out.println("Father init");
}
static int b = 2;
}
class Son extends Father{
static {
System.out.println("Son init");
m = 300;
}
static int m = 100;
static final int M = 1;
}
6. 三种ClassLoader#
package com.onlineframework;
public class ReflectionTest07 {
public static void main(String[] args) throws ClassNotFoundException {
//获取系统类的加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//系统类加载器的父类加载器 --> 扩展类加载器
//负责jre/lib/ext目录下的jar包加载,或者 -D java.ext.dirs 指定目录下的jar包加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
//扩展类加载器的父类加载器 --> 根加载器(C/C++),无法直接获取
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
//sun.misc.Launcher$AppClassLoader@18b4aac2
//sun.misc.Launcher$ExtClassLoader@1b6d3586
//null
ClassLoader classLoader = Class.forName("com.onlineframework.ReflectionTest07").getClassLoader();
System.out.println(classLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2
ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader1); //跟加载器:null
System.out.println(System.getProperty("java.class.path"));
/* C:\Program Files\Java\jdk1.8.0_271\jre\lib\charsets.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\deploy.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\access-bridge-64.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\cldrdata.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\dnsns.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\jaccess.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\jfxrt.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\localedata.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\nashorn.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\sunec.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\sunjce_provider.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\sunmscapi.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\sunpkcs11.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\ext\zipfs.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\javaws.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\jce.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\jfr.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\jfxswt.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\jsse.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\management-agent.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\plugin.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\resources.jar;
C:\Program Files\Java\jdk1.8.0_271\jre\lib\rt.jar;
C:\Users\perfxlab_000\IdeaProjects\jbasic\target\classes;
F:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\lib\idea_rt.jar
*/
//双亲委派机制:自定义的类例如 java.lang.String 无法替代根加载器加载的类,提高安全性
}
}
7. 获得类的信息#
package com.onlineframework;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//获得类的信息
public class ReflectionTest08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("com.onlineframework.User");
System.out.println(c1.getName()); //获得包名+类名 com.onlineframework.User
System.out.println(c1.getSimpleName()); //获得类名 User
System.out.println("======================================================");
for (Field field : c1.getFields()) { //只能找到public属性
System.out.println(field);
}
//Field name = c1.getField("name"); // 获取不到
System.out.println("==============getDeclaredFields============================");
for (Field declaredField : c1.getDeclaredFields()) { //获得所有属性
System.out.println(declaredField);
}
Field name1 = c1.getDeclaredField("name");
System.out.println(name1);
System.out.println("==============getMethods=======================");
for (Method method : c1.getMethods()) { //获得所有public方法(包括父类),不包括所有private
System.out.println(method);
}
System.out.println("==============getDeclaredMethods=======================");
for (Method declaredMethod : c1.getDeclaredMethods()) { //只获得该类内方法,包括private
System.out.println(declaredMethod);
}
System.out.println("==============getMethod=======================");
Method getName = c1.getMethod("getName", null);
System.out.println(getName);
System.out.println(c1.getMethod("setName", String.class));
System.out.println("==============getConstructors (public only)=======================");
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("==============getDeclaredConstructors (all)=======================");
Constructor[] declaredConstructors = c1.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
System.out.println("==============getDeclaredConstructor=======================");
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, Integer.TYPE, Integer.TYPE);
System.out.println(declaredConstructor);
}
}
8. 通过反射动态创建对象#
package com.onlineframework;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//通过反射动态创建对象
public class ReflectionTest09 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class c1 = Class.forName("com.onlineframework.User");
User newInstance = (User)c1.newInstance(); //无参构造器
System.out.println(newInstance); // User{name='null', id=0, age=0}
//通过构造器创建对象
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
Object aaa = declaredConstructor.newInstance("aaa", 11, 12);
System.out.println(aaa); // User{name='aaa', id=11, age=12}
//通过反射调用方法
User user = (User) c1.newInstance();
Method setName = c1.getMethod("setName", String.class);
setName.invoke(user,"name1");
System.out.println(user); // User{name='name1', id=0, age=0}
//通过反射操作属性(private异常)
Field name = c1.getDeclaredField("name");
//name.set(user,"name2");
System.out.println(user);
//通过反射操作属性
name.setAccessible(true);
name.set(user,"name3");
System.out.println(user);
}
}
9. 反射的性能#
package com.onlineframework;
import javax.jws.soap.SOAPBinding;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//性能问题
public class ReflectionTest10 {
public static void test_ordinary(){
User user = new User();
long startTime = System.currentTimeMillis();
for (int i=0;i< 1000000000 ;i++){
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方法:"+(endTime - startTime) +"ms");
}
public static void test_reflection() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getMethod("getName");
long startTime = System.currentTimeMillis();
for (int i=0;i< 1000000000 ;i++){
getName.invoke(user);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方法:"+(endTime - startTime) +"ms");
}
public static void test_reflection_without_accessible() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getMethod("getName");
getName.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i=0;i< 1000000000 ;i++){
getName.invoke(user);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方法关闭检测:"+(endTime - startTime) +"ms");
}
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
test_ordinary();
test_reflection();
test_reflection_without_accessible();
//普通方法:4ms
//反射方法:2228ms
//反射方法关闭检测:1485ms
}
}
10. 反射获取泛型#
package com.onlineframework;
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 ReflectionTest11 {
public void test1(Map<String,User> map, List<User> list){
System.out.println("test1");
}
public Map<String,User> test2(){
System.out.println("test2");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method1 = ReflectionTest11.class.getMethod("test1", Map.class, List.class);
//获得参数的泛型类型
Type[] genericParameterTypes1 = method1.getGenericParameterTypes();
for (Type type : genericParameterTypes1) {
System.out.println(type);
if(type instanceof ParameterizedType){ //ParameterizedType 参数化类型,例如Collection<String>
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(" "+actualTypeArgument);
}
}
}
System.out.println("======================test2================");
Method test2 = ReflectionTest11.class.getMethod("test2");
Type genericReturnType = test2.getGenericReturnType();
if(genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
11. 注解与反射#
package com.onlineframework;
import java.lang.annotation.*;
public class ReflectionTest12 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("com.onlineframework.Student2");
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation); //@com.onlineframework.Student2Table(value=db_student)
}
//获得注解的value
Student2Table c1Annotation = (Student2Table)c1.getAnnotation(Student2Table.class);
System.out.println(c1Annotation.value());//db_student
//获得注解的其他属性
Student2Field nameAnnotation = (Student2Field)c1.getDeclaredField("name").getAnnotation(Student2Field.class);
System.out.println(nameAnnotation.col());//db_name
}
}
@Student2Table("db_student")
class Student2 {
@Student2Field(col = "db_name",type = "char",length = 10)
private String name;
@Student2Field(col = "db_id",type = "int",length = 10)
private int id;
@Student2Field(col = "db_age",type = "int",length = 10)
private int age;
public Student2(){
}
public Student2(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
@Override
public String toString() {
return "Student2{" +
"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;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Student2Table{
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Student2Field{
String col();
String type();
int length();
}