主要内容
详细内容
eclipse使用技巧
Workspace与project关系
一个workspace可以包含多个project,一个workspace保留了eclipse的一套环境选项的配置,比如说编译环境;具体配置可以查看window-->preferences。
Perspective与view关系
一个Perspective代表若干个view的集合;perspective可以通过查看window-->open perspective,view可以通过查看window-->show view。
设置整个workspace的javac和java
设置单个工程的javac和java,选择工程,右键->properties可以设置javac,右键->run asàopen run dialog可以设置java。
注意:高版本的java可以运行低版本的javac编译的程序;但是低版本的java不能运行高版本的javac编译的程序。
快捷键的绑定以及代码模版
快捷键的设置:通过window -->preferences-->General --> keys查看修改,也可以通过组合键“Ctrl+Shift+L”查看基本快捷键设置。
常见快捷键总结:
代码模版:通过window-->preferences-->Java-->Code Style -->Formatter查看修改。
静态导入
静态导入类的静态属性
import static java.lang.System.out;
out.println("haha");
导入类的静态方法
import static java.lang.Math.*; // 导入Math类的所有静态成员
int num = abs(-10);
可变参数与for循环增强
可变参数
当一个方法接受的参数个数不固定时,便可以使用可变参数;有以下三个特点:
(1)只能出现在参数列表的最后;
(2)...位于变量类型和变量名之间,前后有无空格都可以;
(3)调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。
增强for循环
(1)语法格式:
for(type变量名 : 集合变量名)
{
Statements;.
}
(2)注意事项:
i. 迭代变量必须在( )中定义;
ii. 集合变量可以是数组或者实现了Iterable接口的集合类;
(3)示例代码:使用传统方式和增强for循环来实现数组元素相加;
public static int add(int x, int... args)
{
int sum = x;
//使用传统for循环遍历
for (int i = 0; i < args.length; i++)
{
sum += args[i];
}
//使用增强for循环
for (int arg : args)
{
sum += arg;
}
return sum;
}
基本数据类型的自动拆箱和装箱
在Java中,所有的事物都会被看作对象,包括一个数字,基本的Java类型与对应的类之间的关系如下所示:
除此之外关键字void也表示为Class对象。
装箱:自动把一个基本数据类型的数据装箱成一个该类型数据的对象引用;
拆箱:自动把一个基本数据类型的对象引用拆箱成一个基本数据类型的数据,再参与运算。
享元模式(Flyweight Pattern):首先看以下代码:
Integer num1 = 12;
Integer num2 = 12;
System.out.println(num1 == num2);//打印true
Integer num5 = Integer.valueOf(12);
Integer num6 = Integer.valueOf(12);
System.out.println(num5 == num6);//打印true
Integer num3 = 129;
Integer num4 = 129;
System.out.println(num3 == num4);//打印false
为什么前面的返回true,而后面的运算是返回false呢?
对于基本数据类型的整数,装箱成Integer对象时,如果该数值在一个字节内(-128~127),一旦装箱成Integer对象后,就把它缓存在磁里面,当下次,又把该数值封装成Integer对象的时候,先会看看磁里面有没有该对象,有就直接拿出来使用,这样就节省了内存空间。因为比较小的整数,使用的频率比较高,就没有必要对每个对象都分配一个内存空间;这就是享元模式!比如还有26个英文字母。
枚举
产生原因
枚举就是要让某些类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段是无法实现这一目标。
与基本类比较
与普通类相比,主要有以下四点不同点:
(1)枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是继承Object类。其中java.lang.Enum类实现了Serializable和Comparable接口,格式如下所示:
public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable
(2)使用enum定义、非抽象的枚举类默认会使用final修饰,因此枚举类不能派生出子类;
(3)枚举类的构造器只能使用private访问控制符,如果省略了构造器的访问控制符,则默认使用的是private修饰。
(4)枚举类的所有实例必须在枚举类的第一行显式列出,否则这个枚举类永远都不能产生实例。列举这些实例时,系统会自动添加public static final修饰,无须显式添加。
基本应用
使用基本类实现枚举类,需要实现以下三步:
(1)通过private将构造器隐藏起来;
(2)把这个类所有可能实例都使用public static final修饰的类变量来保存;
(3)如果有必要,可以提供一些静态方法,允许其它程序根据特定参数获取与值匹配的实例。
示例代码:定义季节类,这个类只能产生4个对象,将该Season类定义成枚举类;代码如下所示:
public class Season
{
//把Season类定义成不可变的,将其属性也定义成final
private final String name;
private final String desc;
//将构造器定义成private访问权限
private Season(String name, String desc)
{
this.name = name;
this.desc = desc;
}
public static final Season SPRING = new Season("春天","趁春踏青");
public static final Season SUMMER = new Season("夏天","夏日炎炎");
public static final Season FALL = new Season("秋天","秋高气爽");
public static final Season WINTER = new Season("冬天","围炉赏雪");
public String getName()
{
return name;
}
public String getDesc()
{
return desc;
}
}
public class SeasonTest
{
public SeasonTest(Season s)
{
System.out.println(s.getName() + ",这真是一个" + s.getDesc() + "的季节");
}
public static void main(String[] args)
{
new SeasonTest(Season.FALL);
}
}
所有的枚举类都提供了values方法,通过该方法可以遍历获得所有的枚举值;使用枚举实现季节代码如下所示:
public enum SeasonEnum
{
SPRING,SUMMER,FALL,WINTER;
}
public class EnumTest
{
public static void main(String[] args)
{
//所有的枚举类都有一个values方法,返回该枚举类的所有实例
for(SeasonEnum s : SeasonEnum.values())
{
System.out.println(s);
}
new EnumTest().judge(SeasonEnum.SPRING);
}
private void judge(SeasonEnum s)
{
//switch语句中的表达式可以是枚举值
switch (s)
{
case SPRING:
System.out.println("面朝大海,春暖花开");
break;
case SUMMER:
System.out.println("夏日炎炎,适合游泳");
break;
case FALL:
System.out.println("秋高气爽,进补及时");
break;
case WINTER:
System.out.println("冬雪飘飘,适合赏雪");
break;
}
}
}
高级应用
枚举就相当于一个类,可以定义构造方法、成员变量、普通方法和抽象方法;
示例代码:当为枚举类显式定义了带参数的构造器是,列出枚举值时必须对应的传入参数,关于性别的枚举类如下所示:
public enum Gender implements GenderDesc
{
MALE("男"), FEMALE("女");
// 定义一个public修饰的实例变量
public String name;
private Gender(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
}
在枚举类中列出枚举值时,实际就是调用构造器创建枚举类对象,只是无须使用new关键字,也无需显式调用构造器;以上代码实际上等同于以下两行代码:
public static final Gender MALE = new Gender("男");
public static final Gender FEMALE = new Gender("女");
当枚举类实现一个或多个接口时,需要实现该接口包含的方法,假设Gender类继承GenderDesc接口,而GenderDesc接口有info方法,则Gender类中也需要实现info方法,具体代码如下所示:
public interface GenderDesc
{
void info();
}
public enum Gender implements GenderDesc
{
MALE("男")
{
public void info()
{
System.out.println("这个枚举值代表男性");
}
}, FEMALE("女")
{
public void info()
{
System.out.println("这个枚举值代表女性");
}
};
// 定义一个public修饰的实例变量
public String name;
private Gender(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
@Override
public void info()
{
System.out.println("这是一个用于定义性别Field的枚举类");
}
}
在包含抽象方法的枚举类中,每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。
假设有四则运算的操作枚举类,实现了eval()的抽象方法,具体代码如下所示:
public enum Operation
{
PLUS
{
@Override
public double eval(double x, double y)
{
return x + y;
}
},
MINUS
{
@Override
public double eval(double x, double y)
{
return x - y;
}
},
TIMES
{
@Override
public double eval(double x, double y)
{
return x * y;
}
},
DIVIDE
{
@Override
public double eval(double x, double y)
{
return x / y;
}
};
//为枚举类定义一个抽象方法,这个抽象方法由不同的枚举值提供不同的实现
public abstract double eval(double x, double y);
public static void main(String[] args)
{
System.out.println(Operation2.PLUS.eval(34, 34));
System.out.println(Operation2.MINUS.eval(34, 34));
System.out.println(Operation2.TIMES.eval(34, 34));
System.out.println(Operation2.DIVIDE.eval(34, 34));
}
}