Java包/类 库
classpath && path
1、classpath是用来找编译后的class文件的,操作系统或者编译器等会在这些目录下寻找对应的.class文件
2、path时用来找命令行执行文件的,操作系统或者其他软件会在这些目录下找对应的命令行执行文件
3、JAVA_HOME是用来找JDK的
参考:https://www.cnblogs.com/shengulong/p/9965721.html
== 和 equals 区别:
对于 == :
作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
作用于引用类型的变量,则比较的是所指向的对象的地址;
对于 equals:
equals方法不能作用于基本数据类型的变量;
如果没有对Object中equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址,反之则比较的是内容
参考:
https://blog.csdn.net/qq_43410618/article/details/104596614
Java常量池
第一种常量:是一个值,我们将这个值本身称为常量
第二种常量:不可变的变量,我们也称为常量。被关键字final修饰的变量,其值就不可以改变。可能它本身是个变量,但是被final修饰后,我们就可以认为它是个常量
常量池分为两种:静态常量池和运行时常量池。
(1)静态常量池也就是Class字节码文件中的常量池。
(2)运行时常量池:运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外还有一项信息是常量池,它用于存放编译期生成的字面量和符号应用,这部分内容将在类加载后进入方法区的时候存到运行时常量池中。运行时常量池还有个更重要的的特征:动态性。Java要求,编译期的常量池的内容可以进入运行时常量池,运行时产生的常量也可以放入池中。常用的是String类的intern()方法【当调用 intern() 方法时,编译器会将字符串添加到常量池中(stringTable维护),并返回指向该常量的引用】。
常量池是为了避免频繁地创建和销毁对象而影响系统性能,其实现了对象的共享。
例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。
(1)节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。
(2)节省运行时间:比较字符串时,=比equals()快。对于两个引用变量,只用=判断引用是否相等,也就可以判断实际值是否相等。
一般情况下,equals和==是一样的,都是比较的两者的地址值是不是一样。但是也有特殊情况,比如,我们都知道所有类都是继承自Object基类,Object中的equals方法中是使用=来实现的,即比较的是两者的地址值。但是,Object的子类可以重写equals方法,比如Date、String、Integer等类都是重写了equals()方法,比较的是值是否相等。例如,在String类的equals()源码中,先比较是不是指向同一个地址,如果不是再比较两者是不是值相等。这个时候,equals和=所表达的含义显然就不一样了。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
8种基本数据类型都有自己的包装类,其中有6个包装类(Byte,Short,Integer,Long,Character,Boolean)实现了常量池技术。举例来说,通过查看Integer的源码会发现,它有个内部静态类IntegerCache,这个内部静态类进行了缓存,范围是[-128,127],只要是这个范围内的数字都会缓存到里面,从而做成常量池进行管理。我们来看一个实例:
public class IntegerTest {
public static void main(String[] args) {
Integer i1=10;
Integer i2=10;//在[-128-127之间,存入常量池]
System.out.println("i1 ==i2 ---> " + (i1==i2));
Integer i3=1000;
Integer i4=1000;//超出常量池范围,各自创建新的对象
System.out.println("i3 ==i4 ---> " + (i3==i4));
}
}
上述代码中,第一次把i1的值缓存进去了,当创建i2的时候,它其实是指向了第一次缓存进去的那个10,所以i1和i2指向了同一个地址;由于i3和i4均超出了常量池范围,故在堆内存中重新创建了两个对象,它们在堆内存中的地址不相等。
如果使用new关键字,意味着在堆内存中开辟了新的一块内存孔家。每次new一个对象都是在堆内存中开辟一块新的空间,所以每一个new出的对象的地址都不一样。
Float和Double没有实现常量池。
string 类
1.new String都是在堆上创建字符串对象。
2.当调用 intern() 方法时,编译器会将字符串添加到常量池中(stringTable维护),并返回指向该常量的引用。
3.通过字面量赋值创建字符串(如:String str=”twm”)时,会先在常量池中查找是否存在相同的字符串,若存在,则将栈中的引用直接指向该字符串;若不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串
4.常量字符串的“+”操作,编译阶段直接会合成为一个字符串。如string str=”JA”+”VA”,在编译阶段会直接合并成语句String str=”JAVA”,于是会去常量池中查找是否存在”JAVA”,从而进行创建或引用。
5.对于final字段,编译期直接进行了常量替换(而对于非final字段则是在运行期进行赋值处理的)。
final String str1=”ja”;
final String str2=”va”;
String str3=str1+str2;
在编译时,直接替换成了String str3=”ja”+”va”,然后再次替换成String str3=”JAVA”
6.常量字符串和变量拼接时(如:String str3=baseStr + “01”;)会调用stringBuilder.append()在堆内存上创建新的对象。
7.在JDK 1.7后,intern()方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,这一点与之前没有区别,区别在于,如果在常量池中找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。简单的说,就是往常量池放的东西变了:原来在常量池中找不到时,复制一个副本放到常量池,1.7后则是将在堆上的地址引用复制到常量池。
参考:https://www.cnblogs.com/lizhangyong/p/8909329.html
正则表达式
java.util.regex 包主要包括以下三个类:
Pattern 类:
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
Matcher 类:
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
PatternSyntaxException:
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
package hello;
import java.util.regex.*;
public class hello {
public static void main(String[] args){
String content = "I am noob " +
"from runoob.com.";
String pattern = ".*runoob.*";
boolean isMatch = Pattern.matches(pattern, content);
System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch);
}
}
捕获组
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
例如,正则表达式 (dog) 创建了单一分组,组里包含"d",“o”,和"g"。
捕获组是通过从左至右计算其开括号来编号。例如,在表达式((A)(B(C))),有四个这样的组:
((A)(B©))
(A)
(B©)
©
可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。
还有一个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中。
正则表达式语法
在其他语言中,\ 表示:我想要在正则表达式中插入一个普通的(字面上的)反斜杠,请不要给它任何特殊的意义。
在 Java 中,\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。
所以,在其他的语言中(如Perl),一个反斜杠 \ 就足以具有转义的作用,而在 Java 中正则表达式中则需要有两个反斜杠才能被解析为其他语言中的转义作用。也可以简单的理解在 Java 的正则表达式中,两个 \ 代表其他语言中的一个 \,这也就是为什么表示一位数字的正则表达式是 \d,而表示一个普通的反斜杠是 \\。
参考:
https://www.runoob.com/java/java-regular-expressions.html