1 反射机制
1.1 Java程序的三阶段
1.2 反射的优缺点
java">//测试使用new,反射和优化后的反射,执行方法的速度
public class SpeedTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
m1();
m2();
m3();
}
//使用传统new对象的方式
public static void m1() {
Person person = new Person();
long start = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
person.sayHi();
}
long end = System.currentTimeMillis();
System.out.println("m1: " + (end - start));
}
//使用反射的方式
public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<?> personClass = Class.forName("com.yqj.domain.Person");
Object person = personClass.newInstance();
Method sayHi = personClass.getMethod("sayHi");
long start = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
sayHi.invoke(person);
}
long end = System.currentTimeMillis();
System.out.println("m2: " + (end - start));
}
//使用优化后的反射
//1.Method,Field,Constructor 对象都有 setAccessible() 方法
//2.setAccessible 作用是启动和禁用访问安全检查的开关,true为取消访问检查,false开启
public static void m3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<?> personClass = Class.forName("com.yqj.domain.Person");
Object person = personClass.newInstance();
Method sayHi = personClass.getMethod("sayHi");
sayHi.setAccessible(true);
long start = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
sayHi.invoke(person);
}
long end = System.currentTimeMillis();
System.out.println("m2: " + (end - start));
}
}
- result
m1: 5
m2: 2988
m2: 1888
2 Class类
2.1 基本说明
- Class也是类,也继承Object类
- Class类对象不是new出来的,而是系统创建的
java">//ClassLoader 类,不管是new还是反射的方法,第一次创建对象时候均需要通过该类创建单例的Class对象
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
- 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
java">Person person1 = new Person();
Person person2 = new Person();
System.out.println(person1.getClass().hashCode()); //hashCode一致说明是同一个对象
System.out.println(person2.getClass().hashCode());
- 每个类的实例都会记得自己是由哪个Class实例所生成( getClass方法)
- 通过Class对象可以完整地得到一个类的完整结构,通过API
- Class对象存放在堆中
- 类的字节码二进制数据放在方法区,或称为类的元数据
2.2 Class类的常用方法
java">public class ClassBaseMethod {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
String classPath = "com.yqj.domain.Person";
//1.获取Person类对应的Class对象
Class<?> personClass = Class.forName(classPath);
//2.输出Class
System.out.println(personClass); //显示哪个类的Class对象
System.out.println(personClass.getClass()); //显示Class本身
//3.得到包名
System.out.println(personClass.getPackage().getName());
//4.得到全类名
System.out.println(personClass.getName());
//5.创建对象实例
Person person = (Person) personClass.newInstance();
System.out.println(person);
//6.通过反射获取属性
//可以获取包括私有属性
Field age = personClass.getDeclaredField("age");
age.setAccessible(true); //允许访问私有属性
age.set(person,24);
System.out.println(age.get(person));
//类似方法
// personClass.getDeclaredMethod();
// personClass.getMethod();
// personClass.getDeclaredConstructor()
// personClass.getConstructor()
}
}
2.3 获取Class对象的方法
java">public class GetClass {
public static void main(String[] args) throws ClassNotFoundException {
//1.已知类的全类名,且该类在类路径下,可通过Class静态方法forName获取
//多用于配置文件,读取类全路径,加载类
Class personClass1 = Class.forName("com.yqj.domain.Person");
System.out.println(personClass1);
//2.若已知具体的类,通过类的class获取,安全且程序性能最高
//多用于参数传递,比如通过反射得到对应的构造器对象
Class personClass2 = Person.class;
System.out.println(personClass2);
//3.已知某个类的实例,通过getClass方法获取Class对象
//通过创建好的对象,获取Class对象
Class personClass3 = new Person().getClass();
System.out.println(personClass3);
//4.通过类加载器获取Class对象
Class personClass4 = new Person().getClass().getClassLoader().loadClass("com.yqj.domain.Person");
System.out.println(personClass4);
//5.基本数据类型通过class获取
Class intClass = int.class;
System.out.println(intClass);
//6.包装类通过TYPE获取其基本类型的Class对象
Class integerClass = Integer.TYPE;
System.out.println(integerClass);
}
}
2.4 具有Class对象的类型
- 外部类,成员内部类,静态内部类,局部内部类,匿名内部类
- interface接口
- 数组
- enum枚举
- annotation注解
- 基本数据类型
- void
2.5 类加载各阶段任务
- 加载阶段:JVM在该阶段将字节码从不同的数据源(class文件,jar包,网络)转换为二进制字节流加载至内存中,并生成一个代表该类的Class对象
- 连接阶段-验证:为了确保Class文件字节流中包含的信息符合当前虚拟机的要求,包括对文件格式的验证,元数据验证,字节码验证和符号引用验证,可通过 -Xverify:none 关闭
- 连接阶段-准备:JVM在该阶段对静态变量分配内存并默认初始化(0,0L,null,false),这些变量所使用的内存在方法区分配
- 连接阶段-解析:JVM将常量池内的符号引用替换为直接引用的过程
- Initialization初始化:此阶段执行<clinit>() 方法,该方法依次收集类中所有静态变量的赋值动作和静态代码块中的语句,并按顺序进行合并。JVM包装该方法在多线程环境中被正确加锁同步
2.6 通过反射获取结构信息
1. Class类
getName()
getSimpleName()
getFields() 获取所有public修饰的属性,包含本类和父类
getDeclaredFields() 获取本类所有属性
getMethods()
getDeclaredMethods()
getConstructors()
getDeclaredConstructors()
getPackage()
getSuperClass()
getInterfaces()
getAnnotations()
2. Field类
getModifiers() 以int形式返回修饰符,默认修饰符0,public1,private2,protected4,static8,final16,若 public1 + static8 = 9
getType()
getName()
3. Method类
getModifiers()
getReturnType()
getName()
getParameterTypes()
4. Constructor类
getModifiers()
getName()
getParameterTypes()
相关文章
mac m1的go环境配置及使用
1 go环境配置 1.1 下载go的安装包 # 下载地址
https://golang.google.cn/dl/ image-20210716085430669.png1.2 配置环境变量 # 分别在 .bash_profile 和 .zshrc 文件后面追加go的环境变量配置
# 说明:GOPATH表示go的工程根目录,之后的go程序均写在该目录…
Ubuntu20.04LTS 搭建kubernetes集群环境
更换清华源 # 备份源
sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak# 更改源
cd /etc/apt/
sudo vim sources.list# 添加
deb https://mirror.tuna.tsinghua.edu.cn/ubuntu-ports/ focal main restricted universe multiverse
deb https://mirror.tuna.tsinghua.ed…
Excel数据导入到MySQL
在进行数据管理和转移时,经常需要将excel中的数据导入存储至数据库中,本文将导入的方法细化,并进行描述整理。本次数据库的导入操作使用 Navicat Premium 软件。 新建数据表。使用 Navicat Premium 在选定的数据库中新建和excel表对应的字段表…
使用Java操作Docker
本人在做实验过程中,需要通过Java程序部署docker容器。故尝试搜集资料,实现在Java端可以操作部署docker容器。过程中遇到一些bug和坑,在此总结,供有需要的童鞋使用。主体配置以Ubuntu16为例。后面会附加给出mac的配置说明。 docke…
一.Jenkins环境部署
1. Gitlab环境搭建(ubuntu) 下载依赖 sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates
sudo apt-get install -y postfix # 选择 internet site 下载gitlab包 # 若之前卸载过需要删除以下存在的目录
opt/gitlab
etc/gitlab
var/opt/gitlab
v…