一、反射
1.反射是指在运行时检查和操作类、接口、字段、方法等程序结构的能力。通过反射,可以在运行时获取类的信息,创建类的实例,调用类的方法,访问和修改类的字段等
2.反射执行效率低的核心原因
(1) 编译期校验缺失:反射调用绕过编译期类型检查,运行时需动态解析类名、方法名,额外消耗CPU资源。
(2)元数据获取开销:需通过 Class 对象获取方法/字段的元数据(如参数类型、访问权限),涉及JVM内部数据结构查询。
(3)方法调用间接性:通过 Method.invoke() 调用,需处理参数装箱、权限检查,无法直接执行字节码指令。
(4)JIT优化受限:反射操作动态性强,JVM难以对其进行即时编译(JIT)优化,无法生成高效机器码。
//定义一个需要被反射的对象User
public class User {
public String name="张三";
private int age=13;
public void publicMethod(){
System.out.println("do public method");
}
private void privateMethod(){
System.out.println("do private method");
}
public static void staticMethod(){
System.out.println("do static method");
}
public static void main(String[] args) {
try {
//1.反射得到对象
Class<?> clazz=Class.forName("User");
//2.1得到公共方法 getMethod仅能获取公共方法,包括从父类继承的公共方法
Method method=clazz.getMethod("publicMethod");
//2.2 得到私有方法 getDeclaredMethod 能获取类中所有声明的方法,
// 包括public protected 默认 private 但不包含父类继承的方法
Method privateMethod=clazz.getDeclaredMethod("privateMethod");
//设置私有方法可访问
privateMethod.setAccessible(true);
//2.3得到静态方法
Method staticMethod=clazz.getDeclaredMethod("staticMethod");
//3.1反射执行普通方法
method.invoke(clazz.getDeclaredConstructor().newInstance());
//3.2执行私有方法 clazz.getDeclaredConstructor()获取clazz对应类的无参构造方法
//newInstance() 通过构造器,创建该类的实例对象
//privateMethod.invoke 调用privateMethod表示的私有方法,并传入创建好的实例对象
//整体:绕开访问权限
privateMethod.invoke(clazz.getDeclaredConstructor().newInstance());
//3.3执行静态方法
//静态方法:类级别的方法,不需要实例化对象就能调用;而非静态:实例级别,必须依附实例才可执行
staticMethod.invoke(clazz);
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException |
InstantiationException e) {
throw new RuntimeException(e);
}
try {
//1.反射得到对象
Class<?> clazz=User.class; //静态加载;Class.forName("User")--动态加载:运行时根据类名字符串加载,若类为加载会触发加载流程
//2.1反射得到公共属性值
Field field=clazz.getDeclaredField("name");
//2.2反射得到私有属性
Field privateField=clazz.getDeclaredField("age");
//设置私有属性可访问
privateField.setAccessible(true);
//3.1得到公共属性值
String name=(String) field.get(clazz.getDeclaredConstructor().newInstance());
//3.2得到私有属性值
int age=(Integer) privateField.get(clazz.getDeclaredConstructor().newInstance());
//4.打印属性值
System.out.println("name->"+name);
System.out.println("age->"+age);
} catch (NoSuchFieldException | InvocationTargetException | IllegalAccessException | InstantiationException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
二、克隆
1.克隆是指创建一个与原始对象相同的新对象。这个新对象通常具有与原始对象相同的属性和方法,但是它们是两个不同的对象,它们在内存中的位置不同
2.浅克隆[.clone()]与深克隆(不共享)(让所有引用类型的属性实现克隆,或使用 JSON 工具实现深克隆。)--实现:继承Clomeable接口并重写clone()方法
区别在于克隆出来的新对象是否与原始对象共享引用类型的属性
三、链式设置/调用
1.通过设置方法的返回值,让返回值变为对象自身,从而实现连续的方法调用,
2.每个方法返回的是对象自身或包含对象自身的容器,使得可以连续地进行多个操作,从而实现更复杂的功能
3.链式调用常用的三种实现方式:
(1)原生setter
public class Student {
private String name;
private int age;
public Student name(String name) {
this.name = name;
return this;
}
public Student age(int age) {
this.age = age;
return this;
}
}
Student stu = new Student()
.name("磊哥")
.age(18);
(2)@Setter @Getter
@Getter
@Setter
@Accessors(chain = true) //开启链式调用
public class Student {
private String name;
private int age;
}
//调用
Student stu = new Student()
.setName("John")
.setAge(30);
(3)@Builder
import lombok.Builder;
@Builder
public class Student {
private String name;
private int age;
}
Student stu = Student.builder()
.name("磊哥")
.age(18)
.build();
四、Java内存模型 JMM
1.JMM:
(1)为了解决既要CPU性能高,又要不同变量间相互可见
(2)JMM是一种规范,定义Java虚拟机(JVM)和计算机内存协作的工作方式
(3)JMM的价值:保证高效且正确的运行
(4)JMM中重要部分:
工作内存(存储主内存中的数据的副本)、可见性(可通过Volatile实现)、有序性(可通过Sychronized或volatile实现)
(5)volatile
含义:是 Java 中的一个关键字,用于修饰变量。它的核心作用是保证变量的可见性和禁止指令重排序。
作用:
可见性:当一个线程修改了 volatile 变量的值,其他线程能够立即看到这个修改后的值。例如,多个线程操作一个共享的 volatile 变量时,一个线程对它的修改会被快速同步到主内存,其他线程从主内存读取时能获取到最新值。
禁止指令重排序:在一些情况下,Java 编译器和处理器为了优化性能会对指令执行顺序进行重排序, volatile 可以阻止这种重排序,保证代码的执行顺序与预期一致。它常用于多线程环境下对变量的同步操作,不过它不具备原子性(即不能保证复合操作的线程安全,比如 i++ 操作)。
(6)synchronized
含义:是 Java 中的关键字,可用于修饰方法、代码块等,用于实现线程同步,解决多线程环境下的并发问题。
作用:
原子性:保证被 synchronized 修饰的代码块或方法在同一时间只能被一个线程执行,从而避免多线程同时操作共享资源导致的数据不一致问题。
可见性:当线程释放锁时,会将对变量的修改同步到主内存;当线程获取锁时,会从主内存中读取最新的变量值,从而保证了变量的可见性。
可重入性:同一个线程可以多次获取同一把锁,不会出现自己阻塞自己的情况。它是 Java 中实现线程安全的一种重要手段,常用于对共享资源的复杂操作场景,确保操作的原子性和线程安全。
2.计算机内存结构
(1)包括CPU 、一级缓存(L1)、二级缓存(L2)、主内存
(2)主内存与CPU处理器的运算能力指尖存在差距,会引入高速缓存(L2)作为主存与处理器之间的缓冲;CPU将常用的数据放在高速缓存中,运算结束后CPU再将运算结果同步到主内存中,就导致了多个线程在操作时,CPU缓存与主内存数据不一致的问题。
(3)简单说,就是多个指尖,变量是互不可见的。而 JMM就可以解决这种“不一致”的问题
3.happens-before规则(先行执行)
是对JMM规范的具体实现

40万+

被折叠的 条评论
为什么被折叠?



