java复习第十七天

一、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、定义一个枚举,枚举值是课程,每个枚举值有个教师姓名的属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值