day17

来源:互联网 发布:淘宝贷利息多少 编辑:程序博客网 时间:2024/05/01 00:22
一、Java5.0新特性                        
1、编译器的功能更加强大,JVM变化不大 
2、Java在逐渐与C++融合 
3、五小点,四大点 

二、五小点 
1、自动封箱AutoBoxing/自动解封 
   自动封箱和自动拆箱,它实现了简单类型和封装类型的相互转化时,实现了自动转化。  
    byte b     -128~127 
    Byte b     在以上数量的基础上多一个null 

   简单类型和封装类型之间的差别 
   封装类可以等于null  ,避免数字得0时的二义性。 
   Integer i=null; 
   int ii=i;  //会抛出NullException 异常。相当于 int ii=i.intValue(); 
   Integer i=1; //相当于Integer i=new Integer(1); 
   i++;    // i = new Integer(i.intValue()+1); 

   在基本数据类型和封装类之间的自动转换 
   5.0之前 
   Integer i=new Integer(4); 
   int  ii= i.intValue(); 

   5.0之后 
   Integer i=4; 
   Long l=4.3; 
   
   public void m(int i){......} 
   public void m(Integer i){......} 
   以上两个函数也叫方法重载 
   自动封箱解箱只在必要的时候才进行。能不封箱找到匹配的就不封箱。 
   
2、静态引入 StaticImport 
   使用类中静态方法时不用写类名 
   
   System.out.println(Math.round(PI)); 
   可以用以下代码实现: 
   import static java.lang.System.*;  //注意,要写" 类名.* " 
   import static java.lang.Math.*; 
   out.println(round(PI)); 
   
   注意:静态引入的方法不能重名 
   
3、for-each 
   统一了遍历数组和遍历集合的方式   
   for(Object o:list){     //Object o 表示每个元素的类型 ,list 表示要遍历的数组或集合的名字 
       System.out.println(o);  //打印集合或数组中的每个元素 
   } 
   
4、可变长参数 
   处理方法重载中,参数类型相同,个数不同的情况      
   public void m(int... is){.....} 
   
   int... is 相当于一个 int[] is 
   编译器会把给定的参数封装到一个数组中,再传给方法 
   在一个方法中只能有一个可变长参数,而且,必须放在最后一个参数的位置 
   
5、格式化输入/输出 
   java.util.Formatter类 对格式的描述 
   System.out.printf("Hello %s",str);  //打印字符串类型的变量,用一个占位符   
   
   格式化I/O(Formatted I/O) 
   java.util.Sacner类可以进行格式化的输入,可以使用控制台输入,结合了BufferedReader和StringTokener的功能。 
   
三、四大点   
1、枚举 
  枚举是一个类,并且这个类的对象是现成的,在定义类的时候,即定义好了对象 
  程序员要使用的时候,只能从中选择,无权创建 
  enum 枚举名{ 
枚举值1(..),枚举值2(..),.....; 
  } 
  
(1) 在5.0之前使用模式做出一个面向对象的枚举 
    final class Season{ 
public static final Season SPRING=new Season(); 
public static final Season WINTER=new Season(); 
public static final Season SUMMER=new Season(); 
        public static final Season AUTUMN=new Season(); 
        private Season(){} 
    } 
    完全等价于 
    enum Season2{ 
SPRING(..),//枚举值 
SUMMER(..), 
AUTUMN(..), 
WINTER(..) 
    }      
  
    枚举本质上也是一个类,Enum是枚举的父类。 
    这个类编译以后生成一个.class类 
    这个类有构造方法,但是是私有的 
  
    枚举中的values()方法会返回枚举中的所有枚举值 
    枚举中可以定义方法和属性,最后的一个枚举值要以分号和类定义分开,枚举中可以定义的构造方法。 
    枚举不能继承类(本身有父类),但可以实现接口,枚举不能有子类也就是final的,枚举的构造方法是private(私有的)。 
    枚举中可以定义抽象方法,可以在枚举值的值中实现抽象方法。 
    枚举值就是枚举的对象,枚举默认是final,枚举值可以隐含的匿名内部类来实现枚举中定义抽象方法。 
  
(2)枚举类(Enumeration Classes)和类一样,具有类所有特性。Season2的父类是java.lang.Enum; 
    隐含方法: 每个枚举类型都有的方法。 
    Season2[] ss=Season2.values();     ----获得所有的枚举值  
    for(Season2 s:ss){ 
      System.out.println(s.name());   ----- 打印枚举值 
      System.out.println(s.ordinal()); ----- 打印枚举值的编号 
    } 
  
  
(3)  enum可以switch中使用(不加类名)。 
  switch( s ){ 
case SPRING: 
……………. 
case SUMMER: 
……………. 
………….. 
  } 


(4)枚举的有参构造 
  enum Season2{ 
SPRING(“春”),-------------------------------逗号 
SUMMER(“夏”),-------------------------------逗号 
AUTUMN(“秋”),-------------------------------逗号 
WINTER(“冬”);-------------------------------分号 
private String name; 
Season2(String name){    //构造方法必须是私有的,可以不写private,默认就是私有的 
this.name=name; 
        } 
        String getName(){ 
        return name; 
        } 

  } 
  Season2.SPRING.getName()         ---------------------春 
  

(5)枚举中定义的抽象方法,由枚举值实现: 
  enum Operation{ 
ADD('+'){ 
public double calculate(double s1,double s2){ 
return s1+s2; 

}, 
SUBSTRACT('-'){ 
public double calculate(double s1,double s2){ 
return s1-s2; 

}, 
MULTIPLY('*'){ 
public double calculate(double s1,double s2){ 
return s1*s2; 

}, 
DIVIDE('/'){ 
public double calculate(double s1,double s2){ 
return s1/s2; 

}; 
char name; 
public char getName(){ 
return this.name; 

Operation(char name){ 
this.name=name; 

public abstract double calculate(double s1 ,double s2); 
  } 
  有抽象方法枚举元素必须实现该方法。 
  
  Operator[] os = Operator.values(); 
  for(Operator o:os){ 
     System.out.println("8 "+o.name()+" 2="+o.calculate(8,2)); 
  } 
  for(Operator o:os){ 
     System.out.println("8 "+o.getName()+" 2="+o.calculate(8,2)); 
  }  
  
  运行结果: 
  8 ADD 2=10.0 
  8 SUBSTRACT 2=6.0 
  8 MULTIPLY 2=16.0 
  8 DIVIDE 2=4.0 
  8 + 2=10.0 
  8 - 2=6.0 
  8 * 2=16.0 
  8 / 2=4.0 
  
  
2、泛型  
(1)增强了java的类型安全,可以在编译期间对容器内的对象进行类型检查,在运行期不必进行类型的转换。 
   而在java se5.0之前必须在运行期动态进行容器内对象的检查及转换,泛型是编译时概念,运行时没有泛型 

   减少含糊的容器,可以定义什么类型的数据放入容器 
   
(2)List<Integer> aList = new ArrayList<Integer>(); 
   aList.add(new Integer(1)); 
   // ... 
   Integer myInteger = aList.get(0);  //从集合中得到的元素不必强制类型转换 
   支持泛型的集合,只能存放制定的类型,或者是指定类型的子类型。   

   HashMap<String,Float> hm = new HashMap<String,Float>(); 
   
   不能使用原始类型 
   GenList<int> nList = new GenList<int>(); //编译错误 
   
   编译类型的泛型和运行时类型的泛型一定要一致。没有多态。 
   List<Dog> as = new ArrayList<Dog>(); 
   List<Animal> l = as;  //error  Animal与Dog的父子关系不能推导出List<Animal> 与 List<Dog> 之间的父子类关系 
   
(3)泛型的通配符"?"   
   ?   是可以用任意类型替代。 
   <?> 泛型通配符表示任意类型 
   <? extends 类型>  表示这个类型是某个类型或接口的子类型。 
   <? super 类型>    表示这个类型是某个类型的父类型。 

  import java.util.*; 
  import static java.lang.System.*; 
  public class TestTemplate { 
public static void main(String[] args) { 
List<Object> l1=new ArrayList<Object>(); 
List<String> l2=new ArrayList<String>(); 
List<Number> l3=new ArrayList<Number>();  //Number --- Object的子类,所有封装类的父类 
List<Integer> l4=new ArrayList<Integer>(); 
List<Double> l5=new ArrayList<Double>(); 

print(l1); 
print(l2); 
print(l3); 
print(l4); 
print(l5); 

       static void print(List<? extends Number> l){    //所有Number及其子类 l3,l4,l5通过 
for(Number o:l){ 
out.println(o); 


       static void print(List<? extends Comparable> l){……}    //任何一个实现Comparable接口的类 l2,l4,l5通过 
       static void print(List<? super Number> l){……}          //所有Number及其父类 l1,l3通过 
      // "?"可以用来代替任何类型, 例如使用通配符来实现print方法。 
       public static void print(GenList<?> list){……} //表示任何一种泛型 

  } 

(4)泛型方法的定义 --- 相当于方法的模版 
  把数组拷贝到集合时,数组的类型一定要和集合的泛型相同。 
  <...>定义泛型,其中的"..."一般用大写字母来代替,也就是泛型的命名,其实,在运行时会根据实际类型替换掉那个泛型。 
  在方法的修饰符和返回值之间定义泛型 
  <E> void copyArrayToList(E[] os,List<E> lst){……} 
  static <E extends Number & Comparable> void copyArrayToList(E[] os,List<E> lst){……}   //定义泛型的范围 类在前接口在后 
  static<E , V extends E> void copyArrayToList(E[] os,List<E> lst){……} //定义多个泛型 
  "super"只能用在泛型的通配符上,不能用在泛型的定义上 
  
  import java.util.*; 
  public class TestGenerics3 { 
public static void main(String[] args) { 
List<String> l1=new ArrayList<String>(); 
List<Number> l2=new ArrayList<Number>(); 
List<Integer> l3=new ArrayList<Integer>(); 
List<Double> l4=new ArrayList<Double>(); 
List<Object> l5=new ArrayList<Object>(); 
String[] s1=new String[10]; 
Number[] s2=new Number[10]; 
Integer[] s3=new Integer[10]; 
Double[] s4=new Double[10]; 
Object[] s5=new Object[10]; 
copyFromArray(l1,s1); 
copyFromArray(l2,s2); 
copyFromArray(l3,s3); 
copyFromArray(l4,s4); 
copyFromArray(l5,s5); 


//把数组的数据导入到集合中 
public static <T extends Number&Comparable> void copyFromArray(List<T> l,T[] os){ 
for(T o:os){ 
l.add(o); 


  } 
  
  受限泛型是指类型参数的取值范围是受到限制的. extends关键字不仅仅可以用来声明类的继承关系, 也可以用来声明类型参数(type parameter)的受限关系. 
  泛型定义的时候,只能使用extends不能使用 super,只能向下,不能向上。 
  调用时用<?>定义时用 <E> 
  
(5)泛型类的定义 
  类的静态方法不能使用泛型,因为泛型类是在创建对象的时候产生的。 
  class MyClass<E>{ 
public void show(E a){ 
System.out.println(a); 

public E get(){ 
return null; 


  } 

  受限泛型 
  class MyClass <E extends Number>{ 
public void show(E a){ 


  }  
  
3、注释 
4、并发 


四、反射 reflect 
  反射,在运行时,动态分析或使用一个类进行工作。 
  反射是一套API,是一种对底层的对象操作技术 
1、类加载 
  类加载,生成.class文件,保存类的信息  
  类对象,是一个描述这个类信息的对象,对虚拟机加载类的时候,就会创建这个类的类对象并加载该对象。 
  Class,是类对象的类。称为类类。只有对象才会被加载到虚拟机中。一个类只会被加载一次。  
  
2、获得类对象的三种方式:(类对象不用new的方法得到的) 
1)也可以用 类名.Class,获得这个类的类对象。 
2)用一类的对象掉用a.getClass(),得到这个对象的类型的类对象。 
3)也可以使用Class.forName(类名)(Class类中的静态方法),也可以得到这个类的类对象, 
  (注意,这里写的类名必须是全限定名(全名),是包名加类名,XXX.XXX.XXXX)。强制类加载,这种方法是经常使用的。 
  
  一个类的类对象是唯一的。 
  在使用Class.forName(类名)时,如果使用时写的类名的类,还没有被加载,则会加载这个类。 
  
  Class c; 
  c.getName(); 返回类名 
  c.getSuperclass(); 这个方法是获得这个类的父类的类对象。 
  c.getInterfaces(); 会获得这个类所实现的接口,这个方法返回是一个类对象的数组。 
  
  方法对象是类中的方法的信息的描述。java.lang.reflect.Method,方法类的对象可以通过类对象的getMethods() 方法获得, 
  获得的是一个方法对象的数组,获得类中的定义的所有方法对象,除了构造方法。 

  构造方法对象,是用来描述构造方法的信息。java.lang.reflect.Constructor构造方法类的对象可以通过类对象的getConstructors()方法获得, 
  获得这个类的所有构造方法对象。 

  属性对象,使用来描述属性的信息。java.lang.reflect.Field属性类的对象对象可以通过类对象getFields() 这个方法是获得所有属性的属性对象。 

作业: 
1、通过运行时命令行参数输入一个类名,类出类中所有的方法 
2、实现一个带泛型的堆栈,用来存放Number 
3、实现一个栈,用来存放任意类型 
  方法:遍历,pop,push,从数组拷贝 
4、定义一个枚举,枚举值是课程,每个枚举值有个教师姓名的属性
原创粉丝点击