Eclipse的使用 (myeclipse 10)
工作空间(workspace)、工程(project)
在eclipse下Java程序的编写和运行,及java运行环境的配置。
快捷键的配置,常用快捷键:
内容提示:Alt + /
快速修复:Ctrl + 1
导包:Ctrl + shift + O
格式化代码块:ctrl + shift + F
向前向后:Alt + 方向键
添加注释 Ctrl+Shift+/
除去注释 Ctrl+Shift+\
程序的调试和运行
F5(跳入) F6(跳过) F7(跳出)
JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效、清晰,安全的代码。
静态导入
自动装箱/拆箱
增强for循环
可变参数
枚举
泛型
元数据
静态导入
JDK 1.5 增加的静态导入语法用于导入类的某个静态属性或方法。使用静态导入可以简化程序对类静态属性和方法的调用。
语法:
Import static 包名.类名.静态属性|静态方法|*
例如
import static java.lang.System.out
import static java.lang.Math.*
自动装箱/拆箱
JDK5.0的语法允许开发人员把一个基本数据类型直接赋给对应的包装类变量, 或者赋给 Object
类型的变量,这个过程称之为自动装箱。
自动拆箱与自动装箱与之相反,即把包装类对象直接赋给一个对应的基本类型变量。
典型应用:
List list = new ArrayList();
list.add(1);
int j = (Integer)list.get(0);
增强for循环
引入增强for循环的原因:在JDK5以前的版本中,遍历数组或集合中的元素,需先获得数组的长度或集合的迭代器,比较麻烦!
因此JDK5中定义了一种新的语法——增强for循环,以简化此类操作。增强for循环只能用在数组、或实现Iterator接口的集合类上
语法格式:
for(变量类型 变量 :需迭代的数组或集合){
}
可变参数
测试JDK中具有可变参数的类Arrays.asList()方法。分别传多个参、传数组,传数组又传参的情况。
注意:传入基本数据类型数组的问题。
从JDK 5开始, Java 允许为方法定义长度可变的参数。语法:
public void foo(int … args){
}
注意事项:
调用可变参数的方法时,
编译器将自动创建一个数组保存传递给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数
可变参数只能处于参数列表的最后, 所以一个方法最多只能有一个长度可变的参数
枚举类
为什么需要枚举?
一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。
JDK
5新增的 enum 关键字用于定义一个枚举类。
枚举类具有如下特性:
枚举类也是一种特殊形式的Java类。
枚举类中声明的每一个枚举值代表枚举类的一个实例对象。
与java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的(这点不难理解)。
枚举类也可以实现接口、或继承抽象类。
JDK5中扩展了swith语句,它除了可以接收int, byte, char,
short外,还可以接收一个枚举类型。
若枚举类只有一个枚举值,则可以当作单态设计模式使用。
Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。常用方法:
name()
ordinal()
valueof(Class enumClass, String name)
values() 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便。
student类中
private String name;
private Grade grade; //成绩等级 A:100-90 B:89-80 C: 79-70 D:69-60 E:59-0
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public Grade getGrade(){
return grade;
}
public void setGrade(Grade grade){
this.grade = grade;
}
enum Grade{
A("100-90"){
public String toLocaleGrade(){
return "优";
}
},B("89-80"){
public String toLocaleGrade(){
return "良好";
}
},C("79-70"){
public String toLocaleGrade(){
return "好";
}
},D("69-60"){
public String toLocaleGrade(){
return "及格";
}
},E("59-0"){
public String toLocaleGrade(){
return "没及格";
}
};
private Grade(String score){
this.score = score;
}
private String score;
public String getScore(){
return score;
}
测试Demo中
//给学生类中的grade变量赋值
Student stu = new Student();
stu.setGrade(Grade.D);
//取出学生对象中的grade变量,调用grade对象中的getScore()取出对应的数值:100-90 。。。
System.out.println(stu.getGrade().getScore());
//取出学生对象中的grade变量,调用grade对象中的toLocaleGrade()取出对应的(数值):优,良。。。
System.out.println(stu.getGrade().toLocaleGrade());
//遍历枚举值
for (Grade gg : Grade.values()) {
System.out.println(gg.name()+"\t"+gg.ordinal()); //name()
}
//判断枚举值是否存在
Grade g = Grade.valueOf("A");
if(g==Grade.A){
System.out.println("OK");
}else{
System.out.println("error");
}
//枚举值在switch语句中的用法
Grade g = Grade.B;
switch (g) {
case A:
System.out.println("aaaaaaaa");
break;
case B:
System.out.println("bbbbbbbbbbb");
break;
case C:
System.out.println("ccccccccc");
break;
default:
System.out.println("error");
break;
内省—beanutils工具包
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写。
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert, Class clazz) //
自定义转换器
Introspector构建一个BeanInfo对象。
BeanInfo将一个类的所有属性进行了封装
//属性描述器
PropertyDescriptor[] pds = bf.getPropertyDescriptors();
PropertyDescriptor对象:
Method getReadMethod()
获得应该用于读取属性值的方法。
Method getWriteMethod()
获得应该用于写入属性值的方法。
@Test
public void test1() throws Exception{
//将Student中的所有属性封装到BeanInfo对象中
BeanInfo bf = Introspector.getBeanInfo(Student.class);
//属性描述器
PropertyDescriptor[] pds = bf.getPropertyDescriptors();
// System.out.println(pds.length);
for (PropertyDescriptor pd : pds) {
System.out.println(pd.getName());
}
}
@Test
public void test2() throws Exception{
Student stu = new Student();
//得到指定的属性对象
PropertyDescriptor pd = new PropertyDescriptor("name", Student.class);
Method setter = pd.getWriteMethod();//得到setter方法:setName()
setter.invoke(stu, "tom");
Method getter = pd.getReadMethod(); //得到getter方法:getName()
System.out.println(getter.invoke(stu, null));
}
@Test
public void test3() throws Exception{
Student stu = new Student();
//得到指定的属性对象
PropertyDescriptor pd = new PropertyDescriptor("age", Student.class);
Method setter = pd.getWriteMethod();//得到setter方法:setName()
setter.invoke(stu, 18);
Method getter = pd.getReadMethod(); //得到getter方法:getName()
System.out.println(getter.invoke(stu, null));
}
封装赋值
@Test
public void test1() throws Exception{
Student stu = new Student();
BeanUtils.setProperty(stu, "name", "张三"); //给属性赋值
String s = BeanUtils.getProperty(stu, "name");
System.out.println(s);
}
@Test
public void test2() throws Exception{
Student stu = new Student();
//BeanUtils默认支持8种基本数据类型,自动转换
BeanUtils.setProperty(stu, "age", "18"); //给属性赋值
String s = BeanUtils.getProperty(stu, "age");
System.out.println(s);
}
@Test
public void test3() throws Exception{
Student stu = new Student();
//注册类型转换器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.setProperty(stu, "birthday", "1990-11-12"); //给属性赋值
String s = BeanUtils.getProperty(stu, "birthday");
System.out.println(s);
}
@Test
public void test4() throws Exception{
Student stu = new Student();
//注册类型转换器
ConvertUtils.register(new Converter() {
public Object convert(Class type, Object value) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
if(value instanceof String){
String v = (String) value;
try {
return sdf.parse(v);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
return null;
}
}, Date.class);
BeanUtils.setProperty(stu, "birthday", "1995-11-12"); //给属性赋值
String s = BeanUtils.getProperty(stu, "birthday");
System.out.println(s);
}
@Test
public void test5() throws Exception{
//
Map m = new HashMap();
m.put("name", "张三"); //key名一定要与对象中的变量名一致
m.put("age", "18"); //key名一定要与对象中的变量名一致
m.put("birthday", "1992-05-12"); //key名一定要与对象中的变量名一致
Student stu = new Student();
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.populate(stu, m); //将Map属性自动放到Bean中
System.out.println(stu.getName());
}
泛型(Generic)—泛形的作用
JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如:
JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。
注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
泛形的基本术语,以ArrayList为例:<>念着typeof
ArrayList<E>中的E称为类型参数变量
ArrayList<Integer>中的Integer称为实际类型参数
整个称为ArrayList<E>泛型类型
整个ArrayList<Integer>称为参数化的类型ParameterizedType
泛型典型应用
使用迭代器迭代泛形集合中的元素。
使用增强for循环迭代泛形集合中的元素。
存取HashMap中的元素。
使用泛形时的几个常见问题:
使用泛形时,泛形类型须为引用类型,不能是基本数据类型
ArrayList<String> list = new ArrayList(); ArrayListlist = new ArrayList<String>(); ArrayList<String> list = new ArrayList (); ArrayList list = new ArrayList<String>();
泛型方法
ava程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:
,T可以是任意字母,但通常必须要大写。通常需放在方法的返回值声明之前。例如:
public static void doxx(T t);
编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素。
注意:
只有对象类型才能作为泛型方法的实际参数。
在泛型中可以同时有多个类型,例如:
public static V getValue(K key) { return map.get(key);}
泛型类和反射泛形
如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:
public class GenericDao<T>{
private T field1;
public void save(T obj){}
public T getId(int id){}
}
注意,静态方法不能使用类定义的泛形,而应单独定义泛形。
泛形的典型应用:BaseDao和反射泛型
public BaseDao{
Type type = this.getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType)type;
clazz = (Class)pt.getActualTypeArguments()[0]
}
泛型的高级应用——通配符
定义一个方法,接收一个集合,并打印出集合中的所有元素,如下所示
void print(Collection<String> c){
for(String e : c) {
System.out.pritln(e);
}
}
问题:该方法只能打印保存了String对象的集合,不能打印其它集合。通配符用于解决此类问题,方法的定义可改写为如下形式:
void print c>{
for(Object : c){
System.out.println(e);
}
}
此种形式下需要注意的是:由于print方法c参数的类型为Collection