天天看點

JAVA技術增強

從一些視訊教程和資料中自己了解了一些JAVA技術增強的知識,寫進部落格,留下些筆記:

1、Jnuit測試

@Test

@BeforeClass(類加載時運作,方法必須是為static) @AfterClass(類加載時運作,方法為static)

@Before(方法運作前運作,方法不能使靜态方法) @After(方法運作後運作,方法不能使靜态方法)

Assert屬于單元測試中的一個類,其中有很多的方法可以滿足測試

Assert.Method() 斷言(期望值與傳回值是否相同得到方法測試是否通過)

2、Java 5.0新特性

1)靜态導入 import static java.lang.System.out;  程式中可以這樣使用:out.println("");

2)自動拆箱裝箱 Integer i = 1;//裝箱 int j = i; //拆箱

  例子: List list = new ArrayList();

list.add(new Integer(1));//無自動拆箱裝箱

list.add(2); //自動拆箱裝箱

3)增強for循環 隻能用在數組、或實作Iterable接口的集合類上(隻适合取資料)

4)可變參數 

public void sum(int ...nums){

//可變參數把它看做數組

int sum = 0;

(int i : nums){

sum += i;

}

System.out.println(sum);

} //調用 sum(1, 2, 3), sum(1, 2, 3, 4, 5)

//注意:可變參數要放到其他不變參數的後面

int nums[] = {1, 2, 3};

List list = Arrays.asList(nums);//可變參數

System.out.println(list);//細節注意,當數組是基本資料類型是,nums會作為一個對象

5)枚舉

1)class Grade{

private Grade(){}

public static final Grade A = new Grade();

public static final Grade B = new Grade();

public static final Grade C = new Grade();

public static final Grade D = new Grade();

}//等同于

enum Grade{

A, B, C, D;//可以定義構造函數,字段,方法等等,它就是個特殊形式的java類

//但是構造函數必須是私有的,枚舉就是為了解決限定一定範圍的值,即不可以再讓他人建立對象

}

//注意:如果枚舉類中含有有參數的構造函數,需要使用有參數的構造函數聲明,如A("100-90")

2)抽象枚舉:即枚舉類中含有抽象方法,則建立枚舉對象是要實作抽象方法,如:

A("100-90"){

public void 抽象方法(){}

}

3)//枚舉類中隻有一個值,相當于使用單态模式定義出了一個類

4)//枚舉類均是繼承了java.lang.Enum類的孩子

//繼承的方法:name()(傳回名字) ordinal()(傳回序号)

//valueOf(Grade.class, "B") (傳回字元串是枚舉值中的枚舉對象,如果不是,會報異常)

//values()傳回枚舉類的所有的枚舉值

3、反射

加載類,并解剖出類的各個組成部分

注意:

1)靜态方法調用不用對象,method.invoke(null, 參數)

2)調用main方法

調用main方法

public void test() throws Exception{

Class clazz = Class.forName("");

Method method = clazz.getMethod("main", String[].class);

method.invoke(null,new Object[]{new String[]{"aa","bb"}});

//JDK更新相容

//jdk1.5 Method.invoke(Object obj,Object...args);

//jdk1.4 Method.invoke(Object obj,Object obj[]);

//jdk1.4 Method.invoke(Object obj,Object obj[]{"ss", "bb");

//相當于Method.invoke(Object obj,String a,String b);為了保證相容,會把數組拆分

//故寫成new Object[]{new String[]{"aa","bb"}}或者(Object)new String[]{"aa","bb"}

//當使用反射時,若參數為數組,注意上述問題

}

4、内省

開發架構時,經常需要使用java對象的屬性來封裝程式的資料,每次都使用反射技術完成此類操作過于麻煩,是以sun公司開發了一套API,專門用于操作java對象的屬性

Introspector-BeanInfo-PropertyDescriptor[]或者PropertyDescriptor

BeanUtils apache開發(commons-beanutils包)

5、泛型

1)Map<K,V> K和V必須是對象類型,即必須是引用類型

2)ArrayList<String> list = new ArrayList();

ArrayList list = new ArrayList<String>();//為保證相容這樣可以,但是兩邊均有泛型,則兩邊必須一樣

3)泛型提供給javac編譯器使用的,它用于限定集合的輸入類型,讓編譯器在源代碼級别上,即擋住向集合中插入非法資料。但編譯器編譯完帶有泛型的java程式後,生成的class檔案中不在帶有泛型資訊,以此使程式中運作效率不受到影響,這個過程稱之為“擦除”

4)泛型方法

public <T> T a(T t){} //調用a("aaa")

public <T, E, K> void b(T t, E e, K k){}

public class Demo<T>{} //在類上聲明泛型,則整個類都有效,但是對于靜态方法要重新聲明

5)泛型的基本術語,以ArrayList<E>為例

ArrayList<E>中的E稱為類型參數變量

ArrayList<Integer>中的Integer稱為實際類型參數

整個稱為ArrayList<E>泛型類型

整個ArrayList<E>稱為參數化的類型ParameterizedType

6)類上聲明泛型典型應用

1- //使用到了Hibernate

public class BaseDao<T> {

private Session session;

private Class clazz;

public BaseDao(Class clazz) {

this.clazz = calzz;

}

public void add(T t) {

session.save(t);

}

public T find(String id) {

return (T) session.get(clazz,id);

}

public void update(T t) {

session.update(t);

}

public void delete(String id) {

T t = (T) session.get(clazz,id);

session.delete(t);

}

}

2- //寫一個dao繼承BaseDao

public class BookDao extends BaseDao<Book> {

public BookDao () {

super(Book.class);

}

//自動擁有了增删改查方法

}

更優雅的設計:

1- public class BaseDao<T> {

private Session session;

private Class clazz;

public BaseDao(){

ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();//BaseDao<Category>//得到參數化類型,如:BaseDao<class>

clazz = (Class) pt.getActualTypeArguments()[0];

}

public void add(T t) {

session.save(t);

}

public T find(String id) {

return (T) session.get(clazz,id);

}

public void update(T t) {

session.update(t);

}

public void delete(String id) {

T t = (T) session.get(clazz,id);

session.delete(t);

}

}

2- //寫一個dao繼承BaseDao

public class BookDao extends BaseDao<Book> {

//自動擁有了增删改查方法

}

7)通配符

1-<?>使用了問号 通配符,就不能調用與泛型相關(帶泛型的方法)的方法

2-<? extends Number>則實際參數類型隻能是Number的子類(限定處理類型)

2-<? super Integer>則實際參數類型隻能是Integer>的父類(限定處理類型)

以上是Java技術增強的粗略知識架構,好多也都是易錯的東西,按照這個知識架構展開,就可以基本掌握Java技術增強的知識了,更加詳細的知識點需要我們查閱相關資料,這也是自己在一邊寫一邊回憶學過的知識

JAVA技術增強
JAVA技術增強

補充:

Introspector方式:

</pre><pre name="code" class="java">//得到bean所有的屬性
	@Test
	public void test1() throws IntrospectionException {
//		BeanInfo info = Introspector.getBeanInfo(Person.class);
		BeanInfo info = Introspector.getBeanInfo(Person.class, Object.class);//得到bean自己的屬性
		PropertyDescriptor[] pds = info.getPropertyDescriptors();
		for(PropertyDescriptor pd : pds) {
			System.out.println(pd.getName());
		}
	}
	
	//操縱bean某個屬性
	@Test
	public void test2() throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		Person p = new Person();
		PropertyDescriptor pd = new PropertyDescriptor("age",Person.class);
		Method method = pd.getWriteMethod();
		method.invoke(p, 45);
		Method method1 = pd.getReadMethod();
		System.out.println(method1.invoke(p, null));
	}
	
	//得到bea某個屬性類型
	@Test
	public void test3() throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		Person p = new Person();
		PropertyDescriptor pd = new PropertyDescriptor("age",Person.class);
	
		System.out.println(pd.getPropertyType());
	}
           

beanUtils方式:

<span style="white-space:pre">	</span>@Test
	public void test1() throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		
		//為了讓日期賦到bean的birthday屬性上,我們給beanUtils注冊一個日期轉換器
		ConvertUtils.register(new Converter() {


			@Override
			public Object convert(Class type, Object value) {
				if(value==null) {
					return null;
				}
				if(!(value instanceof String)) {
					throw new ConversionException("隻支援String類型的轉換!!");
				}
				String str = (String) value;
				if(str.trim().equals("")) {
					return null;
				}
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				try {
					return sdf.parse(str);
				} catch (ParseException e) {
					throw new RuntimeException(e);
				} catch (java.text.ParseException e) {
					e.printStackTrace();
				}
				return sdf;
			}
			
		}, Date.class);
		
		Person p = new Person();
		BeanUtils.setProperty(p, "name", "jack");
		BeanUtils.setProperty(p, "age", "34");//自動轉換,但是隻支援八種基本資料類型
		
		BeanUtils.setProperty(p, "birthday", "1993-06-01");//需要注冊轉換器
		
		System.out.println(p.getName());
		System.out.println(p.getAge());
		System.out.println(p.getBirthday());
	}
	
	@Test
	public void test2() throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		
		//為了讓日期賦到bean的birthday屬性上,我們給beanUtils注冊一個日期轉換器
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		
		Person p = new Person();
		BeanUtils.setProperty(p, "name", "jim");
		BeanUtils.setProperty(p, "age", "34");//自動轉換,但是隻支援八種基本資料類型
		
		BeanUtils.setProperty(p, "birthday", "1993-06-01");//需要注冊轉換器
		
		System.out.println(p.getName());
		System.out.println(p.getAge());
		System.out.println(p.getBirthday());
	}
	
	@Test
	public void test3() throws IllegalAccessException, InvocationTargetException {
		Map map = new HashMap();
		map.put("name", "aaa");
		map.put("password", "123");
		map.put("age", "23");
		map.put("birthday", "2000-02-01");
		
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		
		Person bean = new Person();
		BeanUtils.populate(bean, map);
		
		System.out.println(bean.getName());
		System.out.println(bean.getAge());
		System.out.println(bean.getBirthday());
	}