概述
本文主要介绍学习Java中遇到的一些比较基础的概念性的东西及一些搞不太清楚的名词解释。以前没有仔细了解过,现在回过头来进行总结下。
一、JDK版本了解
一般情况下,我们下载的JDK版本名称为:jdk-8u101-windows-x64
,我们来简单解释下:
- 8指的是JDK的版本是8.0版本,u指的是update,101代表更新的次数。一般更新的次数为单数的时候,通常只包含补丁文件或一些小的漏洞修复;双数的时候通常包含新功能或新优化之类。
- 详细的可参考R神的回复:[讨论] JDK的版本编号的具体含义
具体的版本历史可参考维基百科:维基百科-Java历史版本
二、JDK、JRE、JVM区别
- JRE : Java Runtime Environment, Java 运行环境,JRE由JVM,Java运行时类库,动态链接库等组成;
- JDK : Java Development ToolKit,Java开发工具包(包含了编译器,调试器,javadoc等),用于开发和运行Java程序;
- JVM : Java Virtual Machine, Java 虚拟机,负责将编译产生的字节码转换为特定的机器代码行;
JVM作为JRE的一部分,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM 的主要工作是解释自己的指令集(即字节码)并映射到本地的 CPU 的指令集或 OS 的系统调用。Java语言是跨平台运行的,其实就是不同的操作系统,使用不同的JVM映射规则,让其与操作系统无关,完成了跨平台性。JVM 对上层的 Java 源文件是不关心的,它关注的只是由源文件生成的类文件( class file);
Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。
由于eclipse,idea等开发工具都有自己内置的编译器而不是JDK的bin目录中自带的编译器,所以在安装时,他们只需要JRE就可以了,但是 Eclipse 只是一个平台,也许你用到的其他东西(比如 maven )有需要 JDK 的也说不定;
- 细心的我们可能会发觉,在JDK里也有一份JRE,一般这个被称为Private JRE,另外的那一个被称为Public JRE。而private JRE一般都是JDK内部自己调用:
Public JRE is a Standalone JRE. Any java application running on your system can use this JRE. It can be uninstalled seperately from JDK.
Private JRE is installed inside JDK folder (C:\Program Files (x86)\Java\jdk1.7.0_25\jre). It is used by the tools like javac etc.
引用地址:http://javaconceptoftheday.com/jdk-installation/
Private Versus Public JRE
Installing the JDK also installs a private JRE and optionally a public copy. The private JRE is required to run the tools included with the JDK. It has no registry settings and is contained entirely in a jre directory (typically at C:\Program Files\jdk1.7.0\jre) whose location is known only to the JDK. On the other hand, the public JRE can be used by other Java applications, is contained outside the JDK (typically at C:\Program Files\Java\jre1.7.0), is registered with the Windows registry (at HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft), can be removed using Add/Remove Programs, might be registered with browsers, and might have the java.exe file copied to the Windows system directory (which would make it the default system Java platform).
引用地址:Oracle - Private Versus Public JRE
参考资料:
JDK基础概念及目录结构
Windows的JDK与JRE,java.exe在哪里是谁干了什么
你執行的是哪個 JRE?
三、JDK 8 静态工具类的另一种方式
以前要在Java里实现所谓“静态工具类”(static utility class)的话,通常会做两件事:
- 把class声明为final,以免被继承;
- 声明一个private的空参数列表构造器,以免外部能创建该类的实例。
一个相应的例子就是java.util.Objects
类。不过在JDK 8中,由于接口支持了静态方法,所以我们可以使用接口来作为静态工具类实现的另一个种方式。因为接口默认必须是抽象的,所以不能用final来阻止别人继承或者实现这个接口,不过反正是抽象的,也不能实例化,所以可以用来做静态工具类。
public interface StringUtils {
/* 默认public */
static boolean endsWith(String str, String suffix) {
// ...
}
}
参考:R大博客
四、Java的Objects工具类
在Java.util包下,有一个Objects类,是在JDK1.7版本引入的,final类型,私有构造方法,方法也全是静态方法,作为Object的工具类,提供null-save(空指针安全的)或null-tolerant(可以容忍空指针的)方法,我们来了解一下。
1. equals方法
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
用于比较两个对象是否相等,底层是通过Object对象的equals方法来实现,通过该静态方法可以避免空指针的出现。不过可能需要注意的是,如果两个对象都是null,该方法返回的是true;如果有一个是null,则会返回false。
2. deepEquals方法
public static boolean deepEquals(Object a, Object b) {
if (a == b)
return true;
else if (a == null || b == null)
return false;
else
return Arrays.deepEquals0(a, b);
}
深度比较,其实就是对列表,数组类型的比较,可以看到,比较的方式是通过Arrays的deepEquals0方法来进行的。
3. hashCode方法
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
计算对象的hashCode值,如果是null,返回0,同样是通过Object的hashCode方法来实现的。
4. hash方法
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
为一个数组或序列生成hashCode,底层是通过Arrays的hashCode方法来实现,其实相当于计算数组的hashCode。这个方法对于在包含多个字段的对象上重写Object.hashCode()非常有用。例如,如果一个对象有三个字段,x, y和z,可以这样写:
@Override public int hashCode() {
return Objects.hash(x, y, z);
}
需要注意的是,当hash方法的参数是单个对象时,返回的hashCode不等于该对象的hashCode方法返回的值,但可以通过hashCode方法来计算。
5. toString方法
toString方法有两个重载方法:
public static String toString(Object o) {
return String.valueOf(o);
}
public static String toString(Object o, String nullDefault) {
return (o != null) ? o.toString() : nullDefault;
}
其中都是通过调用Object的toString方法来实现,主要是对null的处理不同,上面那个方法参数如果为空,返回一个null
字符串,而下面那个方法可以指定为空时候的默认值。
6. compare方法
public static int compare(T a, T b, Comparator super T> c) {
return (a == b) ? 0 : c.compare(a, b);
}
用于对两个对象的比较,其中需要指定具体的比较器。
7. requireNonNull方法
public static T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
public static T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
public static T requireNonNull(T obj, Supplier messageSupplier) {
if (obj == null)
throw new NullPointerException(messageSupplier.get());
return obj;
}
非空校验方法,第一个方法主要用于方法和构造函数的参数校验,比如:
public Foo(Bar bar) {
this.bar = Objects.requireNonNull(bar);
}
而另一个具有两个参数的方法,在为空的情况下可以指定抛出的具体的错误信息,该方法主要用于对具有多个参数的方法和构造函数进行参数验证,比如:
public Foo(Bar bar, Baz baz) {
this.bar = Objects.requireNonNull(bar, "bar must not be null");
this.baz = Objects.requireNonNull(baz, "baz must not be null");
}
最后一个方法,与requireNonNull(Object, String)方法不同,本方法允许将消息的创建延迟到空检查结束之后
8. isNull方法
public static boolean isNull(Object obj) {
return obj == null;
}
就是判断对象是否为空,返回相应的布尔类型。
9. nonNull方法
public static boolean nonNull(Object obj) {
return obj != null;
}
和isNull方法相对应,判断对象是否非空,返回布尔类型。
五. Mybatis查询时候特殊字符的转义
在使用Mybatis框架,对MySQL使用like进行模糊查询的时候,比如%这些字符都是有特殊含义的,我们在查询的时候需要进行相关的转义,转义的方法可以通过:
private static final String SYMBOL = "%";
/**
* 模糊查询拼接%, 添加/转义符
*
* @param params the params
* @return string
*/
public static String addLikeParams(String params) {
if (StringUtils.isNotBlank(params)) {
params = SYMBOL + params.replaceAll("/", "//")
.replaceAll("%", "/%")
.replaceAll("_", "/_") + SYMBOL;
return params;
}
return null;
}
而在对应的XML文件中可以这样配置:
and nick_name like #{likeName} escape '/'