一、Eclipse的使用
1、快捷键
- 内容提示:Alt+/
- 错误提示:Ctrl+1
- 格式化代码块:Ctrl+Shift+F
- 导包:Ctrl+Shift+O
2、程序的调试
- F5:跳入
- F6:跳过
- F7:跳出
3、Junit
二、枚举
1、为什么需要定义枚举?
一些方法在运行时,他需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5前采用自定义带枚举的类解决,JDK1.5后可以直接使用枚举解决。
2、枚举类有如下的特性:
- 枚举类是一种特殊形式的Java类
- 枚举类中声明的每一个枚举值代表枚举类的一个实例对象
- 与java的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数但枚举类的构造函数必须是私有的
- 枚举类也可以实现接口、或继承抽象类
- JDK1.5还扩展了switch语句,除了可以接收byte、short、int、char类型的数据,还可以接受枚举类型
- 若枚举类只有一个枚举值,则可以当做单例设计模式使用
3、Java中声明的枚举类,均是java.lang.Enum类中的孩子,它集成了Enum类中的所有方法,常见的方法如下:
- name():返回枚举常量的名称
- ordinal():返回枚举常量的序数
- Enum.valueof(Class enumType,String name):返回带指定名称的指定枚举类型的枚举常量
- values():此方法虽然在JDK文档中找不到,但每个枚举类都具有该方法,用来遍历枚举类的所有枚举值
4、练习:请编写一个关于星期几的枚举WeekDay,要求:
- 枚举值:Mon,Tue,Wed,Thu,Fri,Sat,Sun
- 该枚举要有一个方法,调用该方法返回中文格式的星期
public class Demo3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Week s = new Week();
s.setName("今天");
s.setGrade(Grade.Mon);
String str = Grade.Mon.getValue();
String str1 = Grade.Mon.toLocalGrade();
System.out.println(str+":"+str1);
}
public class Week {
private String name;
private Grade grade;
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;
}
}
}
public enum Grade {
Mon("Monday") {
@Override
public String toLocalGrade() {
return "星期一";
}
},
Tue("Tuesday") {
@Override
public String toLocalGrade() {
return "星期二";
}
},
Wed("Wednesday") {
@Override
public String toLocalGrade() {
return "星期三";
}
},
Thu("Thursday") {
@Override
public String toLocalGrade() {
return "星期四";
}
},
Fri("Friday") {
@Override
public String toLocalGrade() {
return "星期五";
}
},
Sat("Saturday") {
@Override
public String toLocalGrade() {
return "星期六";
}
},
Sun("Sunday") {
@Override
public String toLocalGrade() {
return "星期日";
}
};
private String value;
private Grade(String value){
this.value = value;
}
public String getValue(){
return value;
}
public abstract String toLocalGrade();
}
二、反射
1、什么是反射?
反射就是把Java类中的各种成分映射成一个个的Java对象。例如一个类中有:成员变量,构造方法,方法等信息,利用反射技术可以对一个类进行剖析,把各个组成部分映射成一个个的对象。
2、Class类
- Class类用于表示.class文件
- 如何得到class文件对应的class对象:类名.class,对象.getClass(),Class.forName(“类名‘)
- 数组类型的Class实例对象:Class.isArray()
- 九种实例Class类型:int,short,byte,long,float,double,char,boolean,void
3、Constructor类
- Constructor类的实例对象是代表类的一个构造方法
- 得到类所有构造方法:Constructor[] constructors = Class.forName(”java.lang.String“).getConstructors();
- 得到一个构造方法:Constructor constructor = Class.forName(“java.lang.String”).getConstructor();
- 利用构造方法创建实例对象:String str = constructor.newInstance(“abc’);
- Class类中的newInstance方法也可以创建实例对象,其工作原理是先得到无参的构造函数,在用构造方法创建实例对象
4、Field类
- Field类代表某个类中的一个成员变量
- Field对象是对应类上面的成员变量,而非对象上的
5、Method类
- Method类代表某个列中的一个成员方法
- 得到类中的某一个方法:Method charAt = Class.forName(”java.lang.string“).getMethod(”charAt“,int.class);
- 调用方法:1通常方式str.charAt(1),2反射方式charAt.invoke(str,1);
6、练习:用反射执行某个类中的main方法
public void Test1(){
Class clazz = Class.forName("com.liyongjia.rflex.Person");
Method mehtod = clazz.getMethod("main",String[].class);
method.invoke(null,(object)new String[]{"a","b"});
}
三、JavaBean内省
1、访问JavaBean属性的两种方式:
- 直接调用bean的get和set方法
- 通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式:
- 第一种方式:通过PropertyDescriptor类操作bean的属性;
- 第二种方式:通过Introspector类获得Bean对象的BeanInfo,然后通过BeanInfo来获取属性的描述器,通过属性描述器获取某个属性对应的getter和setter方法,然后通过反射机制来调用这些方法。
2、练习:内省技术访问的两种方式
//Introspector方式
public void test1() throws IntrospectionException{
BeanInfo info=Introspector.getBeanInfo(Person.class);
BeanInfo info2=Introspector.getBeanInfo(Person.class,Object.class);
PropertyDescriptor[] pds=info.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
System.out.println(pd.getName());
//ab age class name password
}
}
//PropertyDescriptor方式
public void test2() throws Exception{
Person p=new Person();
PropertyDescriptor pd=new PropertyDescriptor("age", Person.class);
Method method=pd.getWriteMethod();
method.invoke(p, 45);
System.out.println(p.getAge());//45
method=pd.getReadMethod();
System.out.println(method.invoke(p, null));//45
}
四、BeanUtils工具包
1、Apeche组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此很多程序员使用这套API,简化程序代码的编写
2、beanutils工具包的常用类:
- BeanUtils:
- PropertyUtils
- ConvertUtils.register(Converter convert,Class clazz)
- 自定义转换器
3、练习:常用工具类的示例
@Test
public void test1() throws Exception{
Person p=new Person();
BeanUtils.setProperty(p, "age", 456);
System.out.println(p.getAge());//456
}
@Test
public void test2() throws Exception{
String name="aaaa";
String age="123";
String password="pw";
Person p=new Person();
//支持8种基本类型自动转换
BeanUtils.setProperty(p, "name", name);
BeanUtils.setProperty(p, "age", age);
BeanUtils.setProperty(p, "password", password);
System.out.println(p.getName());//aaaa
System.out.println(p.getAge());//123
System.out.println(p.getPassword());//pw
}
@Test
public void test3() throws Exception{
String birthday="1983-12-1";
//为了让日期赋值到bean的birthday属性上,给beanUtils注册一个日期转换器
//ConvertUtils.register(converter, clazz);
ConvertUtils.register(new Converter(){
public Object convert(Class type, Object value) {
if(value==null) return null;
if(!(value instanceof String)){
throw new ConversionException("只支持String类型的转换");
}
String str=(String)value;
if(str.trim().equals("")) return null;
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd",Locale.US);
try {
return df.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}, Date.class);
Person p=new Person();
BeanUtils.setProperty(p, "birthday", birthday);
System.out.println(p.getBirthday());//pw
System.out.println("___"+BeanUtils.getProperty(p, "birthday"));
}
public void test5() throws Exception {
Map map=new HashMap();
map.put("name", "aaa");
map.put("password", "123");
map.put("brithday", "1980-09-09");
ConvertUtils.register(new DateLocaleConverter(), Date.class);
Person p=new Person();
//用map集合填充bean属性,map关键字和bean属性要一致
BeanUtils.populate(p, map);
}