new Integer
的时候,如果整型字面量的值在-128 ~ 127之间,那么不会new
新的Integer
对象,而是直接引用常量池中的Integer
.
Integer f1 = 100,f2 = 100,f3 = 150,f4 = 150;
f1 == f2
f3 == f4
- 通常我们定义的一个基本数据类型的”变量”,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;而通过new关键字的对象则放在堆空间,堆是gc的主要区域。方法区和堆是各个线程共享的内存区域。栈空间用光了,会引发
StackOverFlowError
,而堆和常量池空间不足则不会引发。 switch
在java 5之前,只能是byte,short,char,int
5引入了枚举,7引入了String
,现在还是不支持long
- 重载是编译时的多态性,重写是运行时的多态性,重写的子类方法要求和父类有相同的返回类型,比父类更好的访问,不能比父类抛出更多的异常
- 接口比抽象类更加抽象,因为抽象类中可以定义构造器,接口不行
- 静态内部类可以有静态成员,而非静态内部类不行
- 静态内部类只能访问外部类的静态成员,非静态可以访问所有
- 静态内部类实例化方法:
new OuterClass.InnerClass()
,非静态内部类实例化方法:new OuterClass().new InnerClass()
- 调用内部静态类的方法:
OuterClass.InnerClass.method(property)
- 实现克隆的两个方法:
- 实现
Cloneable
接口并重写Object类中的clone()
方法; - 实现
Serializable
接口,通过序列化实现克隆;
- 调用
ByteArrayInputStream
或者ByteArrayOutputStream
对象的close
方法没有任何意义,这两个基于内存的流,Gc会自动清理,不像外部资源(文件流); - 接口可以继承接口,抽象类可以实现接口,抽象类继承具体类,也可以继承抽象类;
- 字符串反转
public static String reverse(String str){
if(str == null || str.length<=1)
return str;
return reverse(str.substring(1))+str.charAt(0);
}
finally
是在return
之前执行,也就是说就算在try
中return
了,也必须等finally
执行完成之后才会返回。List,Set
是继承自Collection
接口,而Map
不是。ArrayList
和LinkedList
都是非线程安全的,可以通过工具类Collections.synchronizedList
方法将其转换成线程安全的。Set
和Map
容器都有基于哈希存储和排序树两种实现版本;TreeSet
要求元素必须实现Comparable
接口,TreeMap
的键必须实现Comparable
接口,从而进行排序sleep()
方法是Thread
的静态方法,将cpu
让出去,但是对象的锁依然保持,因此休眠时间结束后,会自动到就绪状态,wait
会把对象锁也放弃,进入到对象的”等待池”中,只有调用对象的notify
才能唤醒等待池中的线程进入“等锁池”;调用wait
方法的前提是拥有此对象的锁,所以调用此方法必须在同步块或同步方法中。ExecutorService(线程池对象)
提供两个方法来拒绝传入新任务,shutdown
会允许以前提交的任务执行完成再终止;shutdownNow
会阻止等待任务执行,并试图停止正在执行的任务。- 多线程的第三种实现方式:java 5 以后,实现
callable
接口,该接口中的call方法可以在线程执行结束时产生一个返回值。 ClassName[] aa = new ClassName[11]
不会触发类的初始化,也就是下面是不会打印出const
的。
public class ConstClass{
static{
System.out.println("const");
}
public static final int value = 123;
}
public class Main{
public static void main(String[] args){
System.out.println(ConstClass.value)
}
}
- 上面第二种调用也不会打印
const
,因为在编译的时候已经把age
放在常量池中了,如果把final
去掉之后就会初始化。 - 类加载机制:
- (1)加载:将
class
文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时结构数据,在堆中生成一个代表这个类的class
对象,作为方法区类数据的访问入口 - (2)链接:将
java
类的二进制代码合并到jvm的运行状态之中的过程。 - (3)验证:确保加载的类信息符合jvm规范,没有安全方面问题。
- (4)准备:正式为类变量(static)分配内存并设置初始值,都在方法区中进行分配。
- (5)解析:虚拟机常量池内的符号引用(还不知道目标的真正地址,只能先用一个唯一的符号代替了一下,比如类引用了另一个类,开始时是不知道另一个类的class的地址的)替换为直接引用的过程
- (6)初始化:初始化阶段是执行”类构造器方法”的过程。类构造器方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的。
- a:当初始化 一个类的时候,如果发现其父类还没有进行过初始化,则需要先初始化其父类的初始化
- b:虚拟机会保证一个“类的构造器方法”在多线程环境中被正确加锁和同步
- c:当访问一个
java
类的静态域时,只有真正声明这个静态变量的类才会被初始化。