Victor's Code Journey
Victor's Code Journey

Java虚拟机-Instrumentation

java Instrumentation(插桩)指的是可以用独立于应用程序之外的代理(agent)程序来监测和协助运行在JVM上的应用程序。这种监测和协助包括但不限于获取JVM运行时状态,替换和修改类定义等。

从Java SE5开始使用JVM TI替代了JVM PI和JVM DI。提供一套代理机制,支持独立于JVM应用程序之外的程序以代理的方式连接和访问JVM。java.lang.instrument是在JVM TI的基础上提供的Java版本的实现。

Instrument 设计的目的是将字节码添加到方法中,收集工具使用的数据。出于这个目的,更改纯粹是附加的,因此这些工具不会修改应用程序状态或行为。此类良性工具的示例包括监控代理、分析器、覆盖分析器和事件记录器。

当然,由于这种检测机制提供了修改现有已编译 Java 类的字节码或添加字节码的能力,所以我们也可以用来动态修改运行的程序代码。

Java泛型

泛型在定义类,接口和方法时使类型(类和接口)成为参数。与方法声明中使用的更熟悉的形式参数非常相似,类型参数为您提供了一种使用不同输入重复使用相同代码的方法。区别在于形式参数的输入是值,而类型参数的输入是类型。使用泛型带来了下面几点优势:

  • 消除代码中的直接转型。

    List<String> list = new ArrayList<String>();
    list.add("hello");
    String s = list.get(0);   // no cast
  • Java编译器对泛型代码进行强类型检查,如果代码违反类型安全,则会发出错误。修复编译时错误比修复运行时错误容易,后者可能很难找到。

  • 通过使用泛型,可以实现对不同类型的集合工作的泛型算法,可以对其进行自定义,类型安全且易于阅读。

Java序列化

“持久化"意味着对象的“生存时间”并不取决于程序是否正在执行——它存活于程序的每一次调用之间。通过序列化一个对象,将其写入磁盘,以后在程序再次调用时,通过反序列化,重新恢复那个对象,就能圆满实现一种“持久”效果。什么是序列化和反序列化?(注意这里仅指 java 自身提供的序列化功能)

  • 把对象转换为字节序列的过程称为对象的序列化。
  • 把字节序列恢复为对象的过程称为对象的反序列化。

Java克隆

Java的所有类都默认继承java.lang.Object类,在java.lang.Object类中有一个方法clone()。JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:

  1. 拷贝对象返回的是一个新对象,而不是一个引用。
  2. 拷贝对象与用 new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。

字节序

字节(英语:Byte),通常用作计算机信息计量单位,不分数据类型,是通信和数据存储的概念。一个字节代表八个比特。比特(英语:Bit,亦称二进制位)指二进制中的一位,是信息的最小单位。那么多个字节如何表示,接下来本文将介绍字节顺序。

Java进程

进程的概念主要有两点:

  • 第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
  • 第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。

Java 处理系统信号

Linux信号量是一种比较原始的进程通信手段。有很多缺陷,可却是理解操作系统的基础概念。java 开放的api中涉及信号量的只有退出信号,即使用Runtime.addShutdownHook()实现jvm退出钩子。但是我们可以通过sun.misc包来实现支持其他信号的处理。

Java SPI 机制

先描述下API(Application Programming Interface )。在java中,我们使用java提供的很多类、类的方法、数据结构来编写我们的应用程序,最终完成我们需求的程序功能,这里的类、方法、数据结构即是jdk提供的api。api的意义,其实就是这些提供给你完成某项功能的类、接口或者方法。

而SPI(Service Provider Interface)是指一些提供给你继承、扩展,完成自定义功能的类、接口或者方法。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。

java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。

Java 异常处理

  1. Java 的基本原理就是“形式错误的代码不会运行”(编译错误=“形式错误的代码”)。
  2. 捕获错误最理想的是在编译期间,最好在试图运行程序以前。然而,并非所有错误都能在编译期间侦测到。有些问题必须在运行期间解决,让错误的缔结者通过一些手续向接收者传递一些适当的信息,使其知道该如何正确地处理遇到的问题。

摘自 <thinking in java 4th>

Java Lambda Function

如果匿名类的实现非常简单,比如只包含一个方法的接口,那么匿名类的语法可能看起来很笨重且不明确。使用Lambda表达式可以更简洁地表达单方法类的实例。

Java不可变对象

可变类和不可变类(Mutable and Immutable Objects)的初步定义:

  1. 可变类:当你获得这个类的一个实例引用时,你可以改变这个实例的内容。
  2. 不可变类:当你获得这个类的一个实例引用时,你不可以改变这个实例的内容。不可变类的实例一但创建,其内在成员变量的值就不能被修改。

Java final 关键字

Java final关键字有以下几个使用场景:

  • 修饰类,代表不可以继承扩展
  • 修饰变量,代表变量不可以修改
  • 修饰方法,代表方法不可以重写

Java位运算符

Java中的位运算符包含以下几种:

  • <<(左移),>>(右移)和 >>>(无符号右移)属于移位运算符。
  • &(位与),|(位或),^(位异或)和~(取反)属于逻辑运算符。

Java虚拟机-字节码指令

Java源码在运行之前都要编译成为字节码格式(如.class文件),然后由ClassLoader将字节码载入运行。在字节码文件中,指令代码只是其中的一部分,里面还记录了字节码文件的编译版本、常量池、访问权限、所有成员变量和成员方法等信息1。本文主要简单介绍不同Java指令的功能。