1 数据类型
数据类型
描述
占用空间
默认值
boolean
布尔值
1字节
false
byte
8位有符号整数
1字节
0
char
16位Unicode字符
2字节
‘\u0000’
short
16位有符号整数
2字节
0
int
32位有符号整数
4字节
0
float
32位单精度浮点数
4字节
0.0f
long
64位有符号整数
8字节
0L
double
64位双精度浮点数
8字节
0.0d
new Integer()
&& Integer.valueOf()
1 2 3 4 5 6 7 Integer integer1 = new Integer (100 );Integer integer2 = new Integer (100 );System.out.println(integer1 == integer2); Integer integer3 = Integer.valueOf(100 );Integer integer4 = Integer.valueOf(100 );System.out.println(integer3 == integer4);
在 valueOf()
方法中,首先检查传入的整数是否在 -128
到 127
的范围内。如果在这个范围内,会返回 IntegerCache 缓存中的对象;如果超出范围,则会创建新的 Integer
对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 private static class IntegerCache { static final int low = -128 ; static final int high; static final Integer cache[]; static { int h = 127 ; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high" ); if (integerCacheHighPropValue != null ) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127 ); h = Math.min(i, Integer.MAX_VALUE - (-low) -1 ); } catch ( NumberFormatException nfe) { } } high = h; cache = new Integer [(high - low) + 1 ]; int j = low; for (int k = 0 ; k < cache.length; k++) cache[k] = new Integer (j++); assert IntegerCache.high >= 127 ; } private IntegerCache () {} } public static Integer valueOf (int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer (i); }
2 String
1 2 3 4 public final class String { private final char value[]; ... }
类
可变性
线程安全性
性能
String
不可变
线程安全
性能较低
StringBuffer
可变
线程安全(使用synchronized
)
性能较高
StringBuilder
可变
非线程安全
性能较高
字符串创建的两种方式对比:
1 2 3 4 5 String s1 = new String ("aaa" );String s2 = "aaa" ;
1 2 3 4 String str1 = new String ("hello" ).intern();String str2 = new String ("hello" ).intern();System.out.println(str1 == str2);
3 运算
StackOverflow: Is Java “pass-by-reference” or “pass-by-value”?
4 继承
4.1 访问修饰符
类
public
:可以被任何其他类访问。
default
:只能被同一包内的类访问。
1 2 3 4 5 6 7 8 public class PublicClass { } class PackagePrivateClass { }
字段(成员变量) /方法(成员方法) :
private
:只能在当前类中访问/调用。
default
:同包内的类可以访问/调用。
protected
:同包内的类和不同包的子类可以访问/调用。
public
:所有类都可以访问/调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class AccessExample { private int privateField; int packagePrivateField; protected int protectedField; public int publicField; private void privateMethod () { } void packagePrivateMethod () { } protected void protectedMethod () { } public void publicMethod () { } }
内部类 :
成员内部类:可以使用所有四种访问修饰符
局部内部类:不能使用访问修饰符
静态内部类:可以使用所有四种访问修饰符
匿名内部类:不能使用访问修饰符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class OuterClass { public class PublicInnerClass { } protected class ProtectedInnerClass { } class PackagePrivateInnerClass { } private class PrivateInnerClass { } public void method () { class LocalInnerClass { } } public static class PublicStaticInnerClass { } private static class PrivateStaticInnerClass { } Runnable runnable = new Runnable () { @Override public void run () { } }; }
4.2 抽象类(abstract)
抽象类 是一种不能被实例化、只能被继承的特殊类,使用 abstract
关键字声明。它可以包含抽象方法(没有实现的方法,由子类实现)和具体方法(有实现的方法),并且可以拥有构造方法、成员变量和静态方法。抽象类主要用于定义子类的共同特征和行为,通过将公共部分抽象到父类中来实现代码重用,同时通过抽象方法强制子类实现特定的行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public abstract class AbstractDataProcessor { public final void processData () { openConnection(); readData(); processBusinessLogic(); saveData(); closeConnection(); } private void openConnection () { System.out.println("Opening database connection..." ); } private void closeConnection () { System.out.println("Closing database connection..." ); } protected abstract void readData () ; protected abstract void processBusinessLogic () ; protected abstract void saveData () ; }
具体实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class UserDataProcessor extends AbstractDataProcessor { @Override protected void readData () { System.out.println("Reading user data..." ); } @Override protected void processBusinessLogic () { System.out.println("Processing user data..." ); } @Override protected void saveData () { System.out.println("Saving processed user data..." ); } }
4.3 接口(interface)
接口是抽象类的延伸 。
修饰符规则:
字段默认是 public static final
方法默认是 public abstract
1 2 3 4 public interface InterfaceExample { int field = 0 ; void method () ; }
访问权限:
所有成员都必须是 public
不允许使用 private
或 protected
1 2 3 4 5 6 7 8 9 public interface InterfaceExample { }
接口演进历史:
Java 8 之前:只能有抽象方法,不能有方法实现。
Java 8 的改进:增加了默认方法和静态方法。
重载(override
) vs 重写(overload
)
5 Object
java.lang.Object
:
1 2 3 4 5 6 7 8 9 10 11 12 private static native void registerNatives () ;public final native Class<?> getClass();public native int hashCode () ;public boolean equals (Object obj) ;protected native Object clone () throws CloneNotSupportedException;public String toString () ;public final native void notify () ;public final native void notifyAll () ;public final native void wait (long timeout) throws InterruptedException;public final void wait (long timeout, int nanos) throws InterruptedException;public final void wait () throws InterruptedException;protected void finalize () throws Throwable;
equals()
vs ==
:
对于基本类型,== 判断两个值是否相等。
对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。
hashCode()
:主要作用是为每个对象提供一个哈希值。默认的实现是 Object
类中提供的实现,它基于对象的内存地址来生成哈希值。每个对象调用 hashCode()
时都会返回一个整数,作为该对象的标识符。hashCode()
方法与 equals()
方法一起工作,用于判断两个对象是否相等。
在哈希表中,不同的对象可能会有相同的哈希值,这种情况称为 哈希冲突 。哈希冲突是无法避免的,但是 hashCode()
方法应该尽量保证哈希值分布均匀,从而减少冲突的概率。
根据 Java 的规范,如果重写了 equals()
方法,那么必须也重写 hashCode()
方法,以确保相等的对象具有相等的哈希值。否则,哈希表可能无法正常工作。
clone()
:
1 2 3 4 5 6 7 8 public class CloneExample implements Cloneable { @Override protected CloneExample clone () throws CloneNotSupportedException { return (CloneExample)super .clone(); } }
浅拷贝 :创建一个新对象,复制原对象的基本数据类型值和引用类型的引用(地址)。
基本类型:直接复制值
引用类型:复制引用,指向同一个对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Address { private String city; } public class ShallowCopyDemo implements Cloneable { private int id; private String name; private Address address; @Override protected Object clone () throws CloneNotSupportedException { return super .clone(); } } ShallowCopyDemo original = new ShallowCopyDemo ();try { ShallowCopyDemo copy = (ShallowCopyDemo) original.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); }
深拷贝 :创建一个新对象,复制原对象的所有字段值,并递归复制所有引用类型的对象。
基本类型:直接复制值
引用类型:创建新对象,递归复制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class Address implements Cloneable { private String city; @Override protected Object clone () throws CloneNotSupportedException { return super .clone(); } } public class DeepCopyDemo implements Cloneable { private int id; private String name; private Address address; public DeepCopyDemo (int id, String name, Address address) { this .id = id; this .name = name; this .address = address; } @Override protected Object clone () throws CloneNotSupportedException { DeepCopyDemo copy = (DeepCopyDemo) super .clone(); copy.address = (Address) address.clone(); return copy; } } DeepCopyDemo original = new DeepCopyDemo (1 , "测试" , new Address ("北京" ));try { DeepCopyDemo copy = (DeepCopyDemo) original.clone(); System.out.println(original.getId() == copy.getId()); System.out.println(); System.out.println(original.getName().equals(copy.getName())); System.out.println(original.getName() == copy.getName()); System.out.println(); System.out.println(original.getAddress() == copy.getAddress()); System.out.println(original.getAddress().getCity().equals(copy.getAddress().getCity())); System.out.println(original.getAddress().getCity() == copy.getAddress().getCity()); } catch (CloneNotSupportedException e) { e.printStackTrace(); }
true
true
true
false
true
true
6 关键字
6.1 final
1 2 3 4 5 6 7 final class FinalClass { } class SubClass extends FinalClass { }
1 2 3 4 5 6 7 8 9 10 11 class Parent { final void finalMethod () { } } class Child extends Parent { void finalMethod () { } }
基本类型
1 2 final int num = 10 ;num = 20 ;
用类型
1 2 3 final StringBuilder sb = new StringBuilder ("hello" );sb.append(" world" ); sb = new StringBuilder ("hi" );
类成员变量
1 2 3 4 5 6 7 8 class Demo { final int value; Demo() { value = 10 ; } }
静态常量
1 2 3 4 class Constants { public static final double PI = 3.14159 ; public static final String PREFIX = "user_" ; }
6.2 static
静态变量
静态方法
静态代码块
静态内部类
静态导入