枚举类
为什么需要枚举?
一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。
JDK 5新增的 enum关键字用于定义一个枚举类。
手动实现枚举类:
通过 private将构造器隐藏起来
把这个类的所有可能实例都使用public static final修饰
属性不应允许被改动,所以应该使用 private final 修饰
上面写法比较麻烦,java中提供了一种更方便的方法----枚举类可以解决上面的问题
JDK 1.5 新增的 enum关键字用于定义枚举类
枚举类也是一种特殊形式的Java类。
枚举类和普通类的区别:
使用 enum定义的枚举类默认继承了 java.lang.Enum 类
枚举类的构造器只能使用private访问控制符
枚举类的所有实例必须在枚举类中显式列出(,分隔 ; 结尾).列出的实例系统会自动添加public static final 修饰
JDK5中扩展了switch语句,它除了可以接收int,byte, char, short外,还可以接收一个枚举类型
若枚举只有一个成员,则可以作为一种单例模式的实现方式
枚举类对象的属性不应允许被改动,所以应该使用 privatefinal 修饰
枚举类的使用 privatefinal修饰的属性应该在构造器中为其赋值
若枚举类显式的定义了带参数的构造器,则在列出枚举值时也必须对应的传入参数
Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。常用方法:
name():返回此枚举常量的名称,在其枚举声明中对其进行声明
ordinal():返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
valueof(Class enumClass, String name):返回带指定名称的指定枚举类型的枚举常量。静态方法
values() 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便。
内省
为什么要学内省?
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。
什么是Java对象的属性和属性的读写方法?
内省访问JavaBean属性的两种方式:
通过PropertyDescriptor类操作Bean的属性
通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后通过反射机制来调用这些方法。
内省是 Java语言对 Bean 类属性的一种缺省处理方法。例如类 A中有属性 name, 可以通过 getName,setName来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这是默认的规则。 Java中提供了一套 API 来访问某个属性的 getter/setter方法。
一般的做法是通过类Introspector来获取某个对象的BeanInfo 信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法
Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert,Class clazz)
自定义转换器
1.使用sun内省api得到某一个bean的所有属性,操作bean的其中一个属性(给属性赋值,以及得到属性的值)。
package com.hbsi.introspector;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Test;
public class Demo1 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
@Test
public void test1() throws Exception{
BeanInfo bi=Introspector.getBeanInfo(Person.class,Object.class);
PropertyDescriptor[] pds=bi.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
String name=pd.getName();
System.out.println(name);
}
}
@Test
public void test2() throws Exception{
Person p=new Person();
BeanInfo bi=Introspector.getBeanInfo(Person.class);
PropertyDescriptor[] pds=bi.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
String name=pd.getName();
if(name.equals("name")){
Method m=pd.getWriteMethod();
m.invoke(p, "abc");
}
}
System.out.println(p.getName());
}
@Test
public void test3() throws Exception{
Person p=new Person();
PropertyDescriptor pd=new PropertyDescriptor("name",p.getClass());
Method m=pd.getWriteMethod();
m.invoke(p, "ffff");
System.out.println(p.getName());
}
@Test
public void test4() throws Exception{
Person p=new Person();
p.setName("abcdef");
PropertyDescriptor pd=new PropertyDescriptor("name", p.getClass());
Method m=pd.getReadMethod();
String str=(String) m.invoke(p, null);
System.out.println(str);
}
}
2.使用beanUitls框架操作bean的属性,自定义转换器
package com.hbsi.beanutils;
importjava.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
importorg.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.junit.Test;
public class Demo1 {
@Test
public void test1() throws Exception{
Person p=new Person();
BeanUtils.setProperty(p, "name", "张三");
System.out.println(p.getName());
}
@Test
public void test2() throws Exception{
ConvertUtils.register(new Converter(){
@Override
public Object convert(Class type, Object value) {
if(value==null){
return null;
}
if(value instanceof String ){
throw new ConversionException("只能转String数据");
}
String s=(String)value;
if(s.trim().equals("")){
return null;
}
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date d;
try {
d = sdf.parse(s);
} catch (ParseException e) {
// TODO Auto-generated catch block
throw new ConversionException("转换错误");
}
return d;
}
}, Date.class);
String name="张三";
String age="23";
String birthday="1980-10-10";
Person p=new Person();
BeanUtils.setProperty(p, "name", name);
BeanUtils.setProperty(p, "age", age);
BeanUtils.setProperty(p, "birthday", birthday);
System.out.println(p.getName()+"……"+p.getAge()+"……"+p.getBirthday());
}
}
/*class MyConver implements Converter{
@Override
public Object convert(Class arg0, Object arg1) {
// TODO Auto-generated method stub
return null;
}
}*/