Java 值传递详解实参实际参数Arguments用于传递给函数/方法的参数必须有确定的值。 形参形式参数Parameters用于定义函数/方法接收实参不需要有确定的值。StringhelloHello!;// hello 为实参sayHello(hello);// str 为形参voidsayHello(Stringstr){System.out.println(str);}值传递方法接收的是实参值的拷贝会创建副本。 引用传递方法接收的直接是实参的地址而不是实参内的值这就是指针此时形参就是实参对形参的任何修改都会反应到实参包括重新赋值。 很多程序设计语言比如 C、 Pascal提供了两种参数传递的方式不过在 Java 中只有值传递。Java 序列化详解序列化将数据结构或对象转换成可以存储或传输的形式通常是二进制字节流也可以是 JSON, XML 等文本格式 反序列化将在序列化过程中所生成的数据转换为原始数据结构或者对象的过程 对于 Java 这种面向对象编程语言来说我们序列化的都是对象Object也就是实例化后的类(Class)但是在 C这种半面向对象的语言中struct(结构体)定义的是数据结构类型而 class 对应的是对象类型。下面是序列化和反序列化常见应用场景对象在进行网络传输比如远程方法调用 RPC 的时候之前需要先被序列化接收到序列化的对象之后需要再进行反序列化 将对象存储到文件之前需要进行序列化将对象从文件中读取出来需要进行反序列化 将对象存储到数据库如 Redis之前需要用到序列化将对象从缓存数据库中读取出来需要反序列化 将对象存储到内存之前需要进行序列化从内存中读取出来之后需要进行反序列化。常见序列化协议有哪些JDK 自带的序列化方式一般不会用 因为序列化效率低并且存在安全问题。比较常用的序列化协议有 Hessian、Kryo、Protobuf、ProtoStuff这些都是基于二进制的序列化协议。像 JSON 和 XML 这种属于文本类序列化方式。虽然可读性比较好但是性能较差一般不会选择。何为反射反射的应用场景了解么 像咱们平时大部分时候都是在写业务代码很少会接触到直接使用反射机制的场景。但是这并不代表反射没有用。相反正是因为反射你才能这么轻松地使用各种框架。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。这些框架中也大量使用了动态代理而动态代理的实现也依赖反射。比如下面是通过 JDK 实现动态代理的示例代码其中就使用了反射类 Method 来调用指定的方法。 另外像 Java 中的一大利器 注解 的实现也用到了反射。为什么你使用 Spring 的时候 一个Component注解就声明了一个类为 Spring Bean 呢为什么你通过一个 Value注解就读取到配置文件中的值呢究竟是怎么起作用的呢这些都是因为你可以基于反射分析类然后获取到类/属性/方法/方法的参数上的注解。你获取到注解之后就可以做进一步的处理。谈谈反射机制的优缺点优点可以让咱们的代码更加灵活、为各种框架提供开箱即用的功能提供了便利缺点让我们在运行时有了分析操作类的能力这同样也增加了安全问题。比如可以无视泛型参数的安全检查泛型参数的安全检查发生在编译时。另外反射的性能也要稍差点不过对于框架来说实际是影响不大的。Java 代理模式详解代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问这样就可以在不修改原目标对象的前提下提供额外的功能操作扩展目标对象的功能。代理模式的主要作用是扩展目标对象的功能比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。BigDecimal 详解浮点数的运算竟然还会有精度丢失的风险吗确实会floata2.0f-1.9f;floatb1.8f-1.7f;System.out.println(a);// 0.100000024System.out.println(b);// 0.099999905System.out.println(ab);// false为什么浮点数 float 或 double 运算的时候会有精度丢失的风险呢 这个和计算机保存小数的机制有很大关系。我们知道计算机是二进制的而且计算机在表示一个数字时宽度是有限的无限循环的小数存储在计算机时只能被截断所以就会导致小数精度发生损失的情况。 这也就解释了为什么十进制小数没有办法用二进制精确表示。就比如说十进制下的 0.2 就没办法精确转换成二进制小数// 0.2 转换为二进制数的过程为不断乘以 2直到不存在小数为止// 在这个计算过程中得到的整数部分从上到下排列就是二进制的结果。0.2*20.4-00.4*20.8-00.8*21.6-10.6*21.2-10.2*20.4-0发生循环