public static Integer valueOf(int i) {
// 我们发现如果传入的数在这个数组范围内, 则直接返回告诉缓存中的对象,否则创建一个新的对象
// 这就是【享元模式】,为了性能而有的设计
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
CacheInteger:
// Integer内部类
private static class IntegerCache {
static final int low = -128;
static final int high;
// 内部是一个静态的不可变缓存数组
static final Integer cache[];
// 这里有一个静态代码块用于进行初始化
static {
// high value may be configured by property
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);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
// 初始化了一个Integer数组,大小为 127 - -128 +1
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
}
foreach循环
JDK1.5提供了foreach循环,冒号左边为当前遍历到的元素,右边为遍历的集合/数组。
public static void foreach() {
String[] strs = new String[]{"a", "b", "c"};
for (String a : strs) {
System.out.println(a);
}
}
foreach遍历不能修改数组/集合
public static void foreach() {
String[] strs = new String[]{"a", "b", "c"};
for (String a : strs) {
a = "1";
}
System.out.println(Arrays.toString(strs));
}
// 运行结果 仍然为 [a, b, c]
public class Test {
static Integer[] integers = new Integer[]{1,2,3,4,5,6,7};
public static void main(String[] args) {
for(Integer i : integers){
}
}
}
变长参数 vararg
private String print(Object... values) {
StringBuilder sb = new StringBuilder();
for (Object o : values) {
sb.append(o.toString())
.append(" ");
}
return sb.toString();
}
变长参数 values 实际还是一个数组类型
静态导入 static iomport
静态导入可以导入Class中的所有static变量以及方法:
import static java.lang.System.err;
import static java.lang.System.out;
import java.io.IOException;
import java.io.PrintStream;
public class StaticImporter {
public static void writeError(PrintStream err, String msg)
throws IOException {
// Note that err in the parameter list overshadows the imported err
err.println(msg);
}
public static void main(String[] args) {
if (args.length < 2) {
err.println(
"Incorrect usage: java com.oreilly.tiger.ch08 [arg1] [arg2]");
return;
}
out.println("Good morning, " + args[0]);
out.println("Have a " + args[1] + " day!");
try {
writeError(System.out, "Error occurred.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
泛型
为什么需要泛型?
List list = new ArrayList();
list.add("A");
list.add(100);
for (int i = 0; i < list.size(); i++) {
String name = (String) list.get(i); //取出Integer时,运行时出现异常
System.out.println("name:" + name);
}
Set s = new TreeSet<Integer>();
Set<String> ss = s; // unchecked warning
s.add(new Integer(42)); // another unchecked warning
Iterator<String> iter = ss.iterator();
while (iter.hasNext())
{
String str = iter.next(); // ClassCastException thrown
System.out.println(str);
}
parameterized vararg type 为什么会发生堆污染警告
有如下参数化可变参数类型的方法会发生堆污染警告:
public static <T> void foo(List<T>... bar) {
for (List<T> ts : bar) {
System.out.println(ts);
}
}
// warning: Possible heap pollution from parameterized vararg type
参数化可变参数类型可能发生堆污染,这是因为,可变参数在编译时期,会做出如下转换:
public static <T> void foo(List<T>... bar) 函数,被转换为
//反编译Day.class
// enum 就是继承Enum类型的类
final class Day extends Enum
{
//编译器为我们添加的静态的values()方法
public static Day[] values()
{
return (Day[])$VALUES.clone();
}
//编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
public static Day valueOf(String s)
{
return (Day)Enum.valueOf(com/zejian/enumdemo/Day, s);
}
//私有构造函数
private Day(String s, int i)
{
super(s, i);
}
//前面定义的7种枚举实例
public static final Day MONDAY;
public static final Day TUESDAY;
public static final Day WEDNESDAY;
public static final Day THURSDAY;
public static final Day FRIDAY;
public static final Day SATURDAY;
public static final Day SUNDAY;
private static final Day $VALUES[];
static
{
//实例化枚举实例
MONDAY = new Day("MONDAY", 0);
TUESDAY = new Day("TUESDAY", 1);
WEDNESDAY = new Day("WEDNESDAY", 2);
THURSDAY = new Day("THURSDAY", 3);
FRIDAY = new Day("FRIDAY", 4);
SATURDAY = new Day("SATURDAY", 5);
SUNDAY = new Day("SUNDAY", 6);
$VALUES = (new Day[] {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
});
}
}
编译器在编译enum时,会生成一个final的 Day 类,并且此类继承 java.lang.Enum
根据枚举元素,生成了七个Day类型的实例对象,并且都是 public static final 修饰,所以,使用enum定义的枚举元素都是一个个Day实例
enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}