Java笔记
1. 常量池技术
常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。
通常一个包装类型实例化两次,会在堆里创建两次该对象,通过该技术,就可以只初始化一次。
实现常量池化的类型:Integer( [-128,127] ),Character( [-128,127]),Short( [-128,127]),Boolean( [0,127])
//Integer
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
//超出范围的数仍然会被重新实例化
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static {
int h = 127;
}
}
//Character
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
//超出范围的数仍然会被重新实例化
}
private static class CharacterCache {
private CharacterCache(){}
static final Character cache[] = new Character[127 + 1];
static {
for (int i = 0; i < cache.length; i++)
cache[i] = new Character((char)i);
}
}
//Boolean
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
Integer i1=100;
Integer i2=100;
System.out.println(i1 == i2);//true
Integer i1 = 100;//等价于Integer i1=Integer.valueOf(100);使用常量池中的数据
Integer i2 = new Integer(100);
System.out.println(i1==i2);// false
Double i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);// 输出 false,为实现常量池技术
2.静态方法内调用非静态成员
静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,然后通过类的实例对象去访问。在类的非静态成员不存在的时候静态成员就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法操作。
调用静态方法无需实例化对象 类名.方法名
对象名.方法名
3.Java无引用传递
- 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型)。
- 一个方法可以改变一个对象参数的状态。
- 一个方法不能让对象参数引用一个新的对象。
4.深拷贝,浅拷贝
-
浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
-
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
5.存储地址
new 创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)
6. String,StringBuilder,StringBuffer
String对象是不可变的
StringBuffer是线程安全的,但效率较低
StringBuilder是线程不安全的,但效率较高(10%-15%)
7.Object类
8.try-catch-finally
public class Test {
public static int f(int value) {
try {
return value * value;
} finally {
if (value == 2) {
return 0;
}
}
}
}
f(2)=0,finally中的语句总会执行,return 0将会覆盖try中的return。
使用try-resources
当在使用需要关闭的资源时,优先使用try-resources
,
//try-catch
Scanner scanner = null;
try {
scanner = new Scanner(new File("D://read.txt"));
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
}
//try-with-resources
try (Scanner scanner = new Scanner(new File("test.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//try-with-resources关闭多个资源
try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new File("test.txt")));
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) {
int b;
while ((b = bin.read()) != -1) {
bout.write(b);
}
}
catch (IOException e) {
e.printStackTrace();
}
9.序列化
序列化就是将对象转换为可取用的格式
对象中某些字段不想序列化可以用transient修饰,序列化的时候会跳过,反序列化的时候会被置为默认值
transient只能修饰变量,不能修饰方法
static变量不属于任何对象,因此不会被序列化
10.IO流
- InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
- OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
流相关的类都是由这四个类派生而来