1.获取所有类型的class对象
package com.test.reflection;
import java.lang.annotation.ElementType;
public class Test02 {
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);
}
}
2.Java内存
堆内存
(1)存放 new 的对象和数组
(2)可以被所有的线程共享,不会存放别的对象引用
栈内存
(1)存放基本变量类型(会包含这个基本类型的具体数值)
(2)引用对象的变量(会存放这个引用在堆里面的具体地址)
方法区
(1)可以被所有的线程共享
(2)包含了所有的class和static变量
3.类的加载与ClassLoader的理解
(1)加载:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的 java.lang.Class 对象
(2)链接:将Java类的二进制代码合并到JVM的运行状态之中的过程
验证:确保加载的类信息符合JVM规范,没有安全方面的问题
准备:正式为类变量( static )分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配
解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程
(3)初始化
执行类构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译器自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。(类构造器是构造类信息的,不是构造该类对象的构造器)
当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化
虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确加锁和同步
获取类的运行时结构
package com.test.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class<?> c1 = Class.forName("com.test.reflection.User");
//获取类的名字
System.out.println(c1.getName()); //获取包名 + 类名
System.out.println(c1.getSimpleName()); //获取类名
System.out.println("===========================");
//获取类的属性
Field[] fields = c1.getFields(); //只能找到public属性
for (Field field : fields) {
System.out.println(field);
}
fields = c1.getDeclaredFields(); //找到全部的属性
for (Field field : fields) {
System.out.println(field);
}
System.out.println("=============================");
//获得指定属性的值
Field name = c1.getField("name");
System.out.println(name);
System.out.println("=============================");
//获得类的方法
Method[] methods = c1.getMethods(); //获得本类及其父类的全部public方法
for (Method method : methods) {
System.out.println(method);
}
methods = c1.getDeclaredMethods(); //获得本类的所有方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("=================================");
//获得指定方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
System.out.println("==================================");
//获得指定的构造器
Constructor<?>[] constructors = c1.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
constructors = c1.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
}
}
动态创建对象执行方法
package com.test.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test04 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获得Class对象
Class<?> c1 = Class.forName("com.test.reflection.User");
Object user1 = c1.newInstance(); //本质上是调用了无参构造器
//通过构造器调用有参构造
Constructor<?> constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
Object user2 = constructor.newInstance("张三",18,10);
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke:激活方法
setName.invoke(user1,"李四");
System.out.println(((User)user1).getName());
//通过反射操作属性 *************************
User user3 = (User)c1.newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,我们需要关闭程序的安全检测,属性或方法的setAccessible(true)=========暴力破解
name.setAccessible(true);
name.set(user3,"王五");
System.out.println(user3.getName());
}
}
反射获取泛型
package com.test.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 Test05 {
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 = Test05.class.getMethod("test01", Map.class, List.class);
Type[] parameterTypes = method.getGenericParameterTypes();
for (Type parameterType : parameterTypes) {
if (parameterType instanceof ParameterizedType){
Type[] typeArguments = ((ParameterizedType) parameterType).getActualTypeArguments();
for (Type typeArgument : typeArguments) {
System.out.println(typeArgument);
}
}
}
}
}
反射获取注解信息
package com.test.reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class Test06 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class<?> c = Class.forName("com.test.reflection.Student");
//通过反射获得注解
Annotation[] annotations = c.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取注解的值
TableLiu tableLiu = c.getAnnotation(TableLiu.class);
String value = tableLiu.value();
System.out.println(value);
//获得字段指定的注解
Field f = c.getDeclaredField("id");
FieldLiu annotation = f.getAnnotation(FieldLiu.class);
System.out.println(annotation.columnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableLiu{
String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldLiu{
String columnName();
String type();
int length();
}
@TableLiu("db_student")
class Student{
@FieldLiu(columnName = "db_id",type = "int",length = 10)
private int id;
@FieldLiu(columnName = "db_age",type = "int",length = 10)
private int age;
@FieldLiu(columnName = "db_name",type = "String",length = 10)
private String name;
public Student() {
}
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;
}
}