package com.cao.basics;
/**
 * final关键字探测
 * @author caoqingrong
 *
 */
public class Test {
	private final int a;
	
	private String name;
	
	public Test(){
		a = 3;
	}
	
	public Test(String name){
		this.name = name;
	}
	
	/**
	 * 该类无法编译通过,因final修饰的属性a可能没有被初始化
	 * final修饰的成员变量有以下集中初始化方式:
	 * 1.声明变量时直接赋值;
	 * 2.在构造方法中赋值,但要注意,如有多个构造方法时,每个构造方法中都得赋值。
	 * 3.如果该成员变量还有static关键字修饰,那么只能在其声明的时候赋值。
	 */
}public class Test {
	//用final关键字声明引用类型成员变量
	private static final StringBuffer sb = new StringBuffer();
	
	public static void main(String[] args) {
		sb.append("abc");  //该行编译通过
		//sb = new StringBuffer();  //该行编译不通过
		
		/**
		 * 小结:对于final关键字修饰的引用类型的成员变量不可更改是指其引用不可修改,其内容是可以修改的
		 */
	}
}public class Test {
	public static void main(String[] args) {
		try{
			String str = null;
			//return;
			System.exit(0);
		}catch (Exception e) {
			System.out.println("catch block!");
		}finally{
			System.out.println("finally block!");
		}
	}
}public class ArraryInterfaceTest {
	public static void main(String[] args) {
		I[] i = new I[2];//编译通过,数组存放对象的地址
		//I i2 = new I();//编译不通过,不能实例化接口类型
		
		i[0] = new J();
		i[1] = new J();
	}
}
interface I{
}
class J implements I{
}
java异常都是继承自java.lang.Throwable类的,java异常分为两种:
(1)checked Exception :必须处理,捕获处理或继续抛出;除运行时异常,别的都是检查异常;
常见checked Exception:NoSuchMethodException、IllegalClassFormatException、DataFormatException、ClassNotFoundException、SQLException
(2)uncheckedException(即:runtimeException):可以不做任何处理,也可以捕获或抛出;运行时异常都继承自RuntimeException,指那些在java虚拟机正常运行期间抛出的异常的超类。
常见的RuntimeException:NullPointerException、UnknownTypeException、SystemException、ClassCastException、BufferOverflowException、IllegalArgumentException等
答案:为了节省内存,因为对于final修饰的属性,在每个对象中都是不能被修改的,只能读,所以用static修饰,作为类变量,这样可节省空间。
package com.cao.basics;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
 * hashCode 探究
 * @author caoqingrong
 *
 */
public class HashSetTest {
	
	public static void main(String[] args) {
		
		Set<String> set = new HashSet<String>();
		
		System.out.println(set.add("xyz"));   //true
		System.out.println(set.add("abc"));   //true
		System.out.println(set.add("xyz"));   //false
		
		for(Iterator<String> iter = set.iterator();iter.hasNext();){
			System.out.println(iter.next());
		}
		
		System.out.println("==================看看下面喽=======================");
		/*==================================================================*/
		
		Set<People> ps = new HashSet<People>();
		
		System.out.println(ps.add(new People("zhangsan")));   //true
		System.out.println(ps.add(new People("lisi")));		  //true
		System.out.println(ps.add(new People("zhangsan")));	  //true
		
		for(Iterator<People> iter = ps.iterator();iter.hasNext();){
			System.out.println(iter.next().getName());
		}
		
		/**
		 * 总结:
		 * 	  1.当向集合set中添加对象时,首先集合计算要增加对象的hashCode码,根据该hashCode码来计算一个位置来存放欲添加对象,如果该位置不存在已有对象,那么集合set认为该对象在集合中不存在,
		 * 	             直接添加进去。如果已存在一个对象,则集合会调用该对象的equals方法,判断欲增加对象与已有对象比较,如果返回false则认为集合中不存在,如果返回true,则认为已存在,不会将该对象加入集合。
		 *    2.当重写equals方法时,必须重写hashCode方法。其中有个原则:如果一个类的两个对象使用equals方法比较时,结果为true,那么两个对象必须具有相同的hashCode。
		 */
		
	}
}
class People{
	private String name;
	
	public People(String name){
		this.name = name;
	}
	
	public String getName(){
		return name;
	}
	@Override
	public boolean equals(Object obj) {
		if(this == obj){
			return true;
		}
		if(obj instanceof People){
			if(null != obj && this.name.equals(((People) obj).name)){
				return true;
			}
		}
		return false;
	}
	@Override
	public int hashCode() {
		return name.hashCode();
	}
	
}
1.HashSet底层使用HashMap实现的;
2.HashMap的key就是放进HashSet的对象,value是一个objec常量t对象;
3.HashMap底层用数组实现。
4.当向HashMap中增加一个对象时,将会调用该对象的hashcode方法获得其hashCode值,然后根据该值计算出一个数组的下标索引(计算数组的一个位置)。
5.将要增加的对象与该位置上的对象进行比较(equals方法),如果相同,那么将该位置上的已有的对象(Entry类型)的value替换掉,如不不相同,则沿着该Entry的链继续重复上述过程,如果到链的最后仍然没有找到与此对象相同的对象,那么这个时候会将该对象增加到数组中,将数组中该位置上的那个Entry对象链接到该对象后面。
6.对于HashSet和HashMap,这样做是为了提高其元素查找效率,使得查找时间不随着Set或Map的大小改变而改变。
1.ArraryList和Vector都是通过数组实现的,ArrayList所有方法都不是同步的,Vector大部分public方式是同步的,因此Vector是线程安全的,也正因为如此,在不考虑多线程的情况下,ArraryList效率较高。
2.LinkedList底层采用链表实现,故LinkedList增加和删除元素的效率很高,而ArrayList相对更差,但由于ArraryList数组实现,其元素是顺序存储的,所以其元素检索速度很快,优于LinkedList。
他们都可以作为逻辑运算符,区别是&&短路,而&不短路。此外&为位运算符,如3&5的结果为1。(换算成二进制进行与运输)
package com.cao.basics;
import java.util.Date;
public class InnerClassTest {
	@SuppressWarnings("deprecation")
	public String getDateStr(Date date){//注意:该参数date为匿名内部类的实例,而非Date的实例。
		return date.toLocaleString();
	}
	public static void main(String[] args) {
		InnerClassTest ict = new InnerClassTest();
		
		String result =  ict.getDateStr(new Date(){//匿名内部类,该类为Date的子类
			public String toLocaleString(){//重写Date类的toLocaleString()方法
				return "hell world!";
			}
		});
		System.out.println(result);
		
		/**
		 * 总结:java有四种内部类,分别为
		 * 1.静态内部类;static inner class
		 * 2.成员内部类;member inner class
		 * 3.局部内部类;local inner class
		 * 4.匿名内部类;anonymous inner class
		 */
	}
}
package com.cao.basics;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class GenericExtendsTest {
	public void method1(List<Object> list){
		
	}
	
	public void method2(){
		method1(new ArrayList<Object>());
		method1(new ArrayList<String>());
		method1(new ArrayList<Integer>());
	}
	
	//method1、method2是否编译通过?答案:不通过。
	
	public void method3(List<? extends Object> list){
		
	}
	
	public void method4(){
		method3(new ArrayList<Object>());
		method3(new ArrayList<String>());
		method3(new LinkedList<Integer>());
	}
	//method3、method4是否编译通过?答案:通过。
	
	public void method5(List<?> list){
		
	}
	
	public void method6(){
		method5(new ArrayList<Object>());
		method5(new ArrayList<String>());
		method5(new LinkedList<Integer>());
	}
	//method5、method6是否编译通过?答案:通过。
	/**
	 * 结论:
	 * 1.关于泛型的继承ArrayList<Object> 继承了  List<Object>类型,而ArrayList<String> 并非继承 List<Object>.
	 * 2.List<?> 等价于 List<? extends Object>
	 * 
	 */
	
}
1.如果某个线程调用了某个对象的wair方法,那么该线程必须拥有该对象的锁(换句话说,如果一个线程调用了某个对象的wait方法,那么wait方法必须要在synchronized中)。
2.如果一个线程调用了某对象的wait方法,那么该线程就会释放该对象的锁。
3.在java对象中,有两种池(锁池和等待池)
4.如果一个线程调用了某个对象的wait方法,那么该线程就进入该对象的锁池中(释放锁),如果未来的某一时刻,另外一个线程调用了该对象的notify或notifyAll方法,那么在该对象等待池中线程就会起来进入对象的锁池中,去等待获得该对象的锁,如果获得锁成功后,那么该线程将继续沿着wait之后的路径去执行。
5.sleep(long time),如果一个线程调用了sleep方法,那么在睡眠的同时,它不会失去对象的锁的所有权。
1.在某个对象的所有synchronized方法中,在某一时刻,只能有一个唯一的一个线程去访问这些synchronized方法。
2.如果一个方法是synchronized方法,那么该sycchronized关键字表示给当前对象上锁(即this);
3.如果一个synchronized方式是静态的,那么该synchronized关键字表示给对象锁对应的Class对象上锁。(每个类不管生成多少个对象,其对应的Class对象只有一个)。
package com.cao.basics.Thread;
public class ThreadSynchTest {
	public static void main(String[] args) {
		C c = new C();
		T1 t1 = new T1(c);
		//c = new C();
		T2 t2 = new T2(c);
		Thread t = new Thread(t2);
		
		t1.start();
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		t.start();
	}
}
class C{
	//private Object object1 = new Object();
	//private Object object2 = new Object();
	public synchronized void hello(){  //static
		//synchronized (object2){
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("HELLO");
		//}
		
	}
	public synchronized void world(){ 
		//synchronized(object1){
			System.out.println("WORLD");
		//}
	}
}
class T1 extends Thread{
	private C c ;
	
	public T1(C c){
		this.c = c;
	}
	
	@Override
	public void run() {
		c.hello();
	}
}
class T2 implements Runnable{
	
	private C c;
	
	public T2(C c){
		this.c = c;
	}
	@Override
	public void run() {
		c.world();
	}
	
}
可以,java中 char表示的长度是16位。如下:
public class CharTest {
	public static void main(String[] args) {
		char c = '好';
		System.out.println(c);
	}
}
原文:http://blog.csdn.net/qubushangming/article/details/44352259