基础加强

来源:互联网 发布:进口商品条码查询软件 编辑:程序博客网 时间:2024/05/17 01:31
junit 测试框架:
 1.@Test(测试相应的方法)
 2.如果要测试全部方法, 可以测试类下面的全部方法。
 3.测试类前面加@Before() 和@After(),只运行一个测试方法时,都会自动运行。
 4.@Before(),@After()在每个测试方法运行前都会运行。
 5.@BeforeClass() ,@AfterClass()在类加载的时候运行。只运行一次。
 6.断言:Assert.(方法很多) 例: Assert.asserEquals("1",p.run());
 7.Map的四种迭代方法:set/entry/for+set/for+entry


可变参数:
 1.具有可变参数的类:Arrays.asList().分别传多个参,传数组,传数组又传参的情况。
 注意事项:调用可变参数的方法时,编译器会自动创建一个数组保存传递
 给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数。
 可以参数只能处于参数列表的最后,所以一个方法最多只能有一个长度的可变参数。
 asList()方法接收的是一个个对象,所以基本数据类型的数组会当成一个数组对象传进去。
 示例程序:
 
 
   public void sum(int ...nums){
  int sum = 0;
  for(int i : nums){
  sum += i;
  }
  System.out.println(sum);
   }
   @Test
   public void test1(){
 sum(1,2,3,4,5); 
 int[] arr ={1,2,3,4,5};
 sum(arr);
   }
   
   @Test
   public void test2(){
  String[] arr1 = {"1","2","3"};
  Integer[] arr2 = {1,2,3};//如果是:int arr2[] ={1,2,3}就会报错。
  List list = Arrays.asList(arr2);
  System.out.println(list);
   }
}
枚举:枚举类有如下特性:
 1.枚举类也是一种特殊形式的java类。
 2.枚举类中声明的每个枚举值代表枚举的一个实例对象。
 3.与java中的普通类一样,在声明枚举类时,也可以声明属性,方法和构造函数,但枚举
   的构造函数,必须是private.
 4.枚举类也可以实现接口,或者继承抽象类。
 5.JDK5中扩展了swith语句,它除了可以接收int,byte,char,shrot,还可以接收枚举类型。
 6.若枚举类只有一个枚举值,则可以当作单态设计模式使用。
 7.JAVA中声明的枚举类,均是java.lan.Enum类的孩子们,它继承了Enum类的所有方法。
   常用方法:name()/ordinal(下标从1开始)/valueof(Class enumClass,String name)
   values()此方法虽然在JDK中找不到,但每个枚举类都具有该方法,它用于遍历枚举的所有枚举值。
示例小程序:
 package cn.zengbao.Day01;


import org.junit.Test;


public class DomeEnum {

@Test
public void test(){
print(Grade.A);
}
public void print(Grade g){
System.out.println(g.getValue());
System.out.println(g.getlocalvalue());
}
@Test
public void test2(){
System.out.println(Grade.A.name());
System.out.println(Grade.B.ordinal());
String str = "B";
Grade g = Grade.valueOf(str);
System.out.println(g.name());
Grade[] g1 = Grade.values();
for(Object obj : g1){
Grade g2 = (Grade) obj;
System.out.print(g2.name());
}
}
}


/*class Grade{
private Grade(){};
private static final Grade A = new Grade();
private static final Grade B = new Grade();
private static final Grade C = new Grade();
private static final Grade D = new Grade();
private static final Grade E = new Grade();
}*/


enum Grade{
A("90-100"){
public  String getlocalvalue(){
return "优";
};
}
,B("80-90"){
public  String getlocalvalue(){
return "良";
};
}
,C("70-80"){
public  String getlocalvalue(){
return "中";
};
}
,D("60-70"){
public  String getlocalvalue(){
return "不合格";
};
}
,E("50-60"){
public  String getlocalvalue(){
return "差";
};
}
;
String str;
private Grade(String str){
this.str = str;
}
public String getValue(){
return str;
}

public abstract String getlocalvalue();;
}


反射:
 一个类有多个组成部分,例如:成员变量,方法和构造方法等。反射就是加载类,并且
 解剖出类的各个组成部分。
加载类:java中有一个Class<T>.这个类表示某个类的字节码。通常通过Class.forName()来完成。
Class对象提供了如下常用方法:可以解构出类里的成员,方法。
  public Constructor getConstructor()
  public Method getMethod()
  public Field getField()
  
  public Constructor getDeclaredConstructor()
  public Method getDeclaredConstractor()
  public Field getDeClaredConstractor()
这些方法分别用于从类中解剖出构造函数,方法和成员变量(属性)。解剖出的成员分别
使用Constractor ,Method,Field对象表示。
加载类的三种方法:
//第一种加载类的方法:
  Class clazz = Class.forName("cn.zengbao.Day01.Person");
  //第二种加载类的方法:
  //Class clazz1 = new Person("tom","123").getClass();
  //第三种加载类的方法:
 // Class clazz2 = Person.class;
构造函数的反射:
    public void test1() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException{
  Class clazz = Class.forName("cn.zengbao.Day01.Person");
 
 Constructor c = clazz.getConstructor(null);
 Person p = (Person) c.newInstance(null);
 Person p4 = (Person) clazz.newInstance();//创建一个无参的构造函数,并且要求要有一个无参的构造函数。
 
 Constructor c1 = clazz.getConstructor(String.class,String.class);
 Person p2 = (Person) c1.newInstance("aaa","1234");
 
 Constructor c2 = clazz.getDeclaredConstructor(String.class);
 c2.setAccessible(true);
 Person p3 = (Person) c2.newInstance("tom");
  }
二反射方法:
    Class clazz = Class.forName("cn.zengbao.Day01.Person");
 Constructor c = clazz.getConstructor(null);
 Person p = (Person) c.newInstance(null);
 Method m = clazz.getMethod("sing", null);
 m.invoke(p, null);
 
 Method m1 = clazz.getMethod("sing", String.class);//第一个对象方法名,第二个参数名
 m1.invoke(p, "tom");//第一个实例对象,第二个参数值。
 
 //反射main方法。这里注意在反射数组的参数方法时,要注意因兼容性问题导致的问题,1.4以前会默认把数组拆分。
 Method m2 = clazz.getDeclaredMethod("main",String[].class);
 //m2.invoke(p, new Object[]{new String[]{"a","b"}});
 m2.invoke(p,(Object)new String[]{"a","b"});


反射字段:
  Class clazz = Class.forName("cn.zengbao.Day01.Person");
 Person pp = (Person) clazz.newInstance();
 Field f = clazz.getField("name");
 Object value = f.get(pp);
 Class type = f.getType();
 if(type.equals(String.class)){
 String svalue = (String) value;
 }
 f.set(pp, "xxxx");
 System.out.println(f.get(pp));
 
 Field f1 = clazz.getDeclaredField("age");
 f1.setAccessible(true);
 System.out.println(f1.get(pp));
  }
  
内省: (属性的概念,set或get方法在Object类中有一个getClass的属性)
  1.技术原由:开发框架时,经常需要使用java对象的属性来封装程序的数据,
  每次都用反射技术完成此类操作过程过于麻烦,所以SUN公司开发了一套API
  专门操作java对象的属性。
  2.内省访问javaBean属性的两种方法:
   第一种: 1.通过PropertyDescriptor类操作Bean的属性。
      2.通过Interospector类获得Bean对象的BeanInfo,然后通过BeanInfo来获取属性的描述器(ProprtyDescriptor)
  通过这个属性描述器就可以获取某个属性对应的get/set方法,然后通过反射机制调用这些方法。
示例小程序:
 @Test
public void test() throws IntrospectionException{
Person1 bean = new Person1();
BeanInfo bi = Introspector.getBeanInfo(Person1.class,Object.class);//后面的一个参数是指不包括。
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
for(PropertyDescriptor pd :pds){
System.out.println(pd.getName());
}
}
@Test
public void test1() throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Person1 p1 = new Person1();
PropertyDescriptor pd = new PropertyDescriptor("name",Person1.class);
Method m = pd.getWriteMethod();
m.invoke(p1, "tom");
m = pd.getReadMethod();
String str = (String) m.invoke(p1, null);
System.out.println(str);
System.out.println(pd.getPropertyType());
}
   第二种:通过Apach提供的BeanUtils包来操作。 
   示例程序:要两个包。BeanUtils 和日志包
   @Test
public void test() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
Person1 p2 = new Person1();
BeanUtils.setProperty(p2, "name", "tom" );
System.out.println(BeanUtils.getProperty(p2, "name"));
}

@Test
public void test1() throws Exception{
Person1 p3 = new Person1();
String name = "marry";
String age = "12";
String brithday = "1990-05-10";
//ConvertUtils.register(new DateLocaleConverter(), Date.class);
ConvertUtils.register(new Converter(){
@Override
public Object convert(Class type, Object value) {
if(value ==null){
return null;
}
if(!(value instanceof String)){
return null;
}
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);
}
}
},Date.class);
BeanUtils.setProperty(p3, "name", name);
BeanUtils.setProperty(p3, "age", age);
BeanUtils.setProperty(p3, "brithday", brithday);
System.out.println(p3.getName());
System.out.println(p3.getAge());//默认支持8种基本的数据类型的转换。
Date date = p3.getBrithday();
System.out.println(date.toLocaleString());//字符串转时间要注册转换器。
}

泛型:(Generic)
 技术原由:
  1.JDK1.5以前,对象保存在集合中会失去其特性,取出时程序员手工进行类型的强制转换,
    这样不可避免就引发程序的一些安全性问题。
  2.JDK5中的泛型允许程序员在编写集合代码时,就限制集合的处理类型,从而把程序运行时可
  能发生的问题,转变为编译时的问题,以此提高程序的可讲读性,和稳定性。
  使用泛型时注意的问题:
   1.使用泛型时,泛型类型须为引用类型,不能是基本数据类型
   2.泛型是提供给javac编译器使用的,它用于限定集合的输入类型,
     让编译器在源代码上,即挡住向集合中插入非法数据,但完成编译器编译后,
     生成的CLASS文件中将不再带有泛型信息,以此使程序不再带有泛型信息,
     以此使程序运行效率不受到影响,这个过程称为“擦除”。
   泛型的基本术语,ArrayList<E>为例:<>念typeof。
   ArrayList<E>中的E称为类型参数变量。
   ArrayList<Integer>中的Integer称为实际类型参数。
   整个称为ArrayList<E>泛型类型。
   整个ArrayList<Inter>称为参数化的类型ParameterizedType.
自定义泛型:
 java程序中普通方法,构造方法,静态方法中都可以使用泛型。
 方法使用泛型前,必须对泛型进行声明,语法:<T>,T可以是任意字母。
 但通常必须大写。<T>通常放在方法的返回值声明之前。
 public static <T> void doxx(T t);
 
 
 注意:只有对象类型才能作为泛型方法的实际参数。
       泛型中可以同时有多个类型。
       public static <K,V>V getValue(K key) {
        return map.get(key);
       }
  练习:1.编写一个泛型方法,实现指定位置上的数组元素的交换。
    2.编写一个泛型方法,接收一个任意数组,并颠倒数组中的所有元素。


自定义泛型----泛型类和反射泛型。
  如果一个类多处都要用到同一个泛型,这时可以泛型定义在类上(即类级别的泛型)
  public class GenericDao<T>{
    private T field1;
    public void save(T obj){}
    public T getId(int id){}
  }
  注意:静态方法不能使用类定义的泛型,面应单独定义泛型。
  泛型的典型应用: BaseDao和反射泛型:
  
0 0