從一些視訊教程和資料中自己了解了一些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技術增強的知識了,更加詳細的知識點需要我們查閱相關資料,這也是自己在一邊寫一邊回憶學過的知識
補充:
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());
}