Java 杂论(持续更新中)
-
Java支持汉字作为classname
-
char
可以存储汉字 -
String 是java中的字符串,它继承于CharSequence。 String 是java中的字符串,它继承于CharSequence。
CharSequence
与String
都能用于定义字符串,但CharSequence
的值是可读可写序列,而String
的值是只读序列(待确定) -
Integer
Integer使用了一个静态内部类(嵌套类),里面包含了一个 缓存数组cache[],默认情况下,[-128, 127]之间的整数会在第一次使用时(类加载时)被自动装箱,放在cache[]数组里。区间的上限值high设置JVM参数-XX:AutoBoxCacheMax来改变,默认情况下参数为127(byte类型的范围),存储在java.lang.Integer.IntegerCache.high属性中。
使用Integer.valueOf()进行构造时,就使用了cache[]缓存数组
Integer 之间比较最好不要用 == 。
- ? 通配符类型
<? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类
<? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
- map 的遍历
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
- (1)final 方法:不允许该类复写(指该方法不可被继承成员重新定义);允许编辑器将对此方法的调用转换为inline调用机制。
内联不一定好,当被指定为内联的方法体很大时,展开的开销可能就已经超过了普通函数调用调用的时间,引入了内联反而降低了性能,因为在选择这个关键字应该慎重些,不过,在以后高版本的JVM中,在处理内联时做出了优化,它会根据方法的规模来确定是否展开调用。
(2)使用final是所谓的安全发布(safe publication)的一种方式: 如果一个对象将会在多个线程中访问并且你并没有将其成员声明为final,则必须提供其他方式保证线程安全
“其他方式”可以包括声明成员为volatile,使用synchronized或者显式Lock控制所有该成员的访问。
当构造函数结束时,final类型的值是被保证其他线程访问该对象时,它们的值是可见的(当声明一个final成员时,必须在构造函数退出前设置它的值)
final类型的成员变量的值,包括那些用final引用指向的collections的对象,是读线程安全而无需使用synchronization的
不可变对象(指所有的成员都是final并且成员要么是基本类型,要么指向另一个不可变对象)可以并发访问而无需使用同步机制。通过final引用读取“实际不可变”对象(指成员虽然实际并不是final,然而却从不会改变)也是安全的。
参考:http://www.cnblogs.com/mianlaoshu/articles/3648403.html
- 在多线程中使用同步容器,如果使用Iterator迭代容器或使用使用for-each遍历容器,在迭代过程中修改容器会抛出ConcurrentModificationException异常。想要避免出现ConcurrentModificationException,就必须在迭代过程持有容器的锁。但是若容器较大,则迭代的时间也会较长。那么需要访问该容器的其他线程将会长时间等待。从而会极大降低性能。----这也是同步容器的缺点,因此发展出并发容器
隐式迭代的情况,如toString,hashCode,equalse,containsAll,removeAll,retainAll等方法都会隐式的Iterate,也可能抛出ConcurrentModificationException。
- try catch finally :return
(1)有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)
可行的做法有四:
1.return语句只在函数最后出现一次。
2.return语句仅在try和catch里面都出现。
3.return语句仅在try和函数的最后都出现。
4.return语句仅在catch和函数的最后都出现。
注意,除此之外的其他做法都是不可行的,编译器会报错。
示例
public class ReturnTest {
public static int func(int arg){
int i = 0;
try {
System.out.println("in try……");
i = 1000 / arg ;
//return i ;
}catch (Exception e){
e.printStackTrace();
System.out.println("in catching ……");
return 1000;
}finally {
System.out.println("in finally ……");
// return 10000;
}
return i;
}
public static void main(String[] args){
System.out.println(ReturnTest.func(0));
}
}
- finalize
finalize()的功能 : 一旦垃圾回收器准备释放对象所占的内存空间, 如果对象覆盖了finalize()并且函数体内不能是空的, 就会首先调用对象的finalize(), 然后在下一次垃圾回收动作发生的时候真正收回对象所占的空间.
在Java中,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行
,显然指望它做收尾工作是靠不住的。
那么finalize()究竟是做什么的呢?它最主要的用途是回收特殊渠道申请的内存
。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。
参考:1
-
CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。
-
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。