一. 注解
1.元注解
/**
* Author:ckvsok
* Date:2021/3/25
**/
package annotation;
import java.lang.annotation.*;
@MyAnnotation
public class test01 {
}
//自定义一个注解
@Target(value = {ElementType.TYPE , ElementType.FIELD , ElementType.METHOD}) //作用目标 : 是个数组(分别是class, 字段 , 方法).....
@Retention(value = RetentionPolicy.RUNTIME) // 表示什么状态有效 .RUNTIME > CLASS > SOURCES
@Documented //注解被包含在javadoc中
@Inherited //表示子类可以继承父类
@interface MyAnnotation {
}
2.注解参数
/**
* Author:ckvsok
* Date:2021/3/25
**/
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@MyAnnotation2(name = "ck", age = 12, id = 1,schools = {"abc","cdv"})
public class Test02 {
@MyAnnotation2(name = "ck")
public void test(){
}
@MyAnnotation2(123) //value 赋值123, "value =" 可以省略其余按默认
public void test2(){
}
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
//注解的参数, 默认值
String name() default "";
int age() default 0;
int id() default -1;
String[] schools() default {""};
int value() default 0;
}
二. 反射
1.获取Class对象
/**
* Author:ckvsok
* Date:2021/3/25
**/
package Reflection;
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
//1、通过 类 获取 Class
Class<Student> studentClass1 = Student.class;
//2、根据类名 获取 Class
Class<?> studentClass2 = Class.forName("Reflection.Student");
//3、通过对象获取类的Class
Student student = new Student();
Class<? extends Student> studentClass3 = student.getClass();
}
}
class Student{
}
2.动态创建对象
/**
* Author:ckvsok
* Date:2021/3/26
**/
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//测试动态获取类的构造方法\方法\字段等
public class Test02 {
public static void main(String[] args) throws Exception {
//获取Class类
Class c1 = Class.forName("Reflection.User");
//反射获取无参构造器
Constructor constructor = c1.getConstructor();
System.out.println(constructor);
//反射获取有参构造器
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class);
System.out.println(declaredConstructor);
//通过构造器新建对象
User ck = (User) declaredConstructor.newInstance("Ck", 27);
System.out.println(ck);
//通过反射调用方法
Method setName = c1.getDeclaredMethod("setName", String.class);
setName.setAccessible(true);//关闭私有检测, 私有方法也可以运行
setName.invoke(ck, "ck2");
System.out.println(ck);
//反射给字段赋值
Field age = c1.getDeclaredField("age");
age.setAccessible(true);//关闭私有检测
age.set(ck,15);
System.out.println(ck);
}
}
class User{
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public User() {
}
public String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
3.反射获取泛型
/**
* Author:ckvsok
* Date:2021/3/27
**/
package Reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
//测试反射获得泛型
public class Test03 {
public static void main(String[] args) throws Exception {
Class c1 = Test03.class;
//获得参数泛型
Method method1 = c1.getMethod("test01", Map.class);
//获得参数信息
Type[] genericParameterTypes = method1.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("--------------------------------------");
//获得返回值泛型
Method method2 = c1.getMethod("test02");
Type genericReturnType = method2.getGenericReturnType();
System.out.println(genericReturnType);
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
public static void test01(Map<String, User> map) {
System.out.println("参数泛型");
}
public static Map<String, Student> test02() {
System.out.println("返回值泛型");
return null;
}
}
4.反射操作注解
/**
* Author:ckvsok
* Date:2021/3/27
**/
package Reflection;
import java.lang.annotation.*;
//反射操作注解
public class Test04 {
public static void main(String[] args) {
Class student2Class = Student2.class;
//获取注解
Annotation annotation = student2Class.getAnnotation(StudentAnnotation.class);
System.out.println(annotation);
//获取注解的值
StudentAnnotation studentAnnotation = (StudentAnnotation) student2Class.getAnnotation(StudentAnnotation.class);
System.out.println(studentAnnotation.age());
}
}
@StudentAnnotation(id = 1, age = 12, name = "ck")
class Student2 {
private int id;
private int age;
private String name;
@Override
public String toString() {
return "Student2{" +
"id=" + id +
", age=" + age +
", 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;
}
public Student2() {
}
public Student2(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface StudentAnnotation {
int id();
int age();
String name();
}
三.Java内存分析
1.堆
-
存放new的对象和数组
-
可以被所有的线程共享
2.栈
- 存放基本变量类型(会包含这个基本类型的具体数值)
- 引用对象的变量(对应堆里的地址)
3.方法区
- 所有的class和static变量
- 可以被所有线程共享
4.类加载过程
- 类的加载Load
- 将类的class文件读入内存,并为之创建一个Class对象。由类加载器完成。
- 类的链接Link
- 将类的二进制数据合并到 JRE 中
- 类的初始化Initialize
- JVM负责对类进行初始化
5.类的初始化
- 发生类初始化
- mian方法所在类
- new一个对象
- 调用类的静态成员(除了final常量)和静态方法
- 使用反射方法对类进行反射调用
- 初始化一个类,如果父类没有被初始化,则会先初始化他的父类
- 不发生类初始化
- 当访问一个静态域时,只有真正声明这个域的类才会被初始化
- 通过数组定义类引用,不会触发此类的初始化
- 引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池中了)