------- android培训、java培训、java学习型技术博客、期待与您交流! ----------
什么是枚举
枚举是一些计算机编程语言的一种构造类型,它用于声明一组命名的常数,
当一个变量有几种可能的取值时,可以将它定义为枚举类型,变量的值只限于列举出来的值的范围内.
当枚举只有一个成员时,就可以作为一个单例。
如何用普通类实现枚举
私有构造方法
每个元素分别用一个公有的静态成员变量表示
可以有若干公有方法或抽象方法
public class WeekDay {
private WeekDay(){}
public final static WeekDay SUN = new WeekDay();
public final static WeekDay MON = new WeekDay();
public WeekDay nextDay(){
if(this == SUN){
return MON;
}else{
return SUN;
}
}
}
采用抽象方法定义nextDay就可以将大量的if else语句转移成一个个独立的内部类。
public abstract class WeekDay {
private WeekDay(){}
public final static WeekDay SUN = new WeekDay(){
public WeekDay nextDay() {
return MON;
}};
public final static WeekDay MON = new WeekDay(){
public WeekDay nextDay() {
return SUN;
}};
public abstract WeekDay nextDay();
}
枚举的基本应用
public class EnumTest {
public static void main(String[] args) {
WeekDay weekday = WeekDay.FRI;
System.out.println(weekday);//枚举中覆盖了toString方法,可以直接打印
System.out.println(weekday.ordinal());//获取对象在枚举中的位置
System.out.println(WeekDay.valueOf("SUN").toString());//通过字符串获取对象
System.out.println(WeekDay.values().length);//获取枚举中的所有对象,以数组形式返回
}
//定义枚举用enum
public enum WeekDay{
SUN,MON,TUE,WED,THI,FRI,SAT //没有其他内容可以不用加分号
}
}
元素初始化的时候默认调用空参数的构造方法,可以在元素后面加()指定调用哪个构造方法
public enum WeekDay{
SUN(1),MON,TUE,WED,THI,FRI,SAT; //元素列表必须位于最前面,需要加分号
//定义两个构造方法
private WeekDay(){
System.out.println("first");
}
private WeekDay(int day){
System.out.println("second");
}
}
使用枚举定义交通灯,把这个学会枚举就差不多了
public enum TrafficLamp{
RED(30){
public TrafficLamp nextLamp(){
return GREEN;
}
},
GREEN(45){
public TrafficLamp nextLamp(){
return YELLOW;
}
},
YELLOW(5){
public TrafficLamp nextLamp(){
return RED;
}
};
public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp(int time){
this.time = time;
}
}
什么是内省
内省(Introspector)是Java语言对Bean类属性、事件的一种缺省处理方法。
JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,有一定难度,
用内省这套api操作JavaBean比用普通类的方式更方便。
什么是JavaBean
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。
这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,JavaBean的属性是根据其中的setter和getter方法来确定的,
而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,至于你把它存到哪个变量上不用管,如果方法名为getId,中文意思即为获取id,
至于你从哪个变量上取也不用管,去掉set和get前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
setId()的属性名 id
isLast()的属性名 last
setCPU()的属性名 CPU
getUPS()的属性名 UPS
总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean。
在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地。
对JavaBean的简单内省操作
//使用流水账的方式进行内省操作的步骤
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3,5);//初始化pt1的x,y的值为3,5
String propertyName = "x"; //需求:获取pt1的x的值
//"x"-->"X"-->"getX"-->MethodGetX
//使用java.beans包里面的属性描述器:PropertyDescriptor(属性名,被当作JavaBean的类);
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
//通过PropertyDescriptor就可以获得x属性的get方法
Method methodGetX = pd.getReadMethod();
//用反射的方式调用get方法,不知道属性类型要用Object,以后可以都使用retVal这个属性名
Object retVal = methodGetX.invoke(pt1);
//通过PropertyDescriptor获得x属性的set方法
Method methodSetX = pd.getWriteMethod();
//用反射的方式调用set方法,和get的区别:不需要返回值,需要传一个参数
methodGetX.invoke(pt1,7);
}
}
//使用eclipse将读取属性和设置属性的流水帐代码分别抽取成方法
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
//选中下面三行代码,将其抽取成方法getProperty,方法中接受pt1和propertyName两个参数
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);
Object value = 7;//设置一个参数,不需要选中,就表示是从外面来的参数
//选中下面三行代码,将其抽取成方法setProperty,方法中需要接受三个参数
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodGetX.invoke(pt1,value);
}
}
用复杂方式进行内省操作 (有了简单的这个了解就行)
private static Object getProperty(Object pt1, String propertyName) throws Exception {
//通过类Introspector来获取某个对象的BeanInfo信息
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
//通过BeanInfo来获取属性的描述器,但是只能获得所有的属性,没有获得单个属性的方法
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
//遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性
Object retVal = null;
for(PropertyDescriptor pd : pds){
if(pd.getName().equals(propertyName))
{
Method methodGetX = pd.getReadMethod();
retVal = methodGetX.invoke(pt1);
break;
}
}
return retVal;
}
使用BeanUtils工具包操作JavaBean
内省知道就行了但是BeanUtils工具包需要确实会用
用eclipse加入jar包
为了在其他机子上也能运行工程,要将jar包放到工程内部,在工程目录下创建lib目录,将beanutils.jar复制进去,
右键添加进Build Path,但是运行会报错, 还需要将日志包login.jar复制进来并添加进Build Path。
BeanUtils.getProperty(pt1,"x");
BeanUtils.setProperty(pt1,"x","9");
BeanUtils中获得和设置的x值都是String类型,因为web开发中,用户填写的数据都是字符串,BeanUtils内部会自动转换。
Date类有个setTime方法,符合JavaBean的要求,BeanUtils支持birthday.time这样的级联操作
private Date birthday; //会报错,没有bean指定
private Date birthday = new Date();//应该这样写
BeanUtils.setProperty(pt1,"birthday.time","111");
BeanUtils.getProperty(pt1,"birthday.time");
BeanUtils的一些其他方法
static void copyProperties(Object dest,Object orig);// 将一个对象身上的属性复制到另一个对象身上
static Map describe(Object bean);// 将JavaBean转换成Map
static void populate(Object bean,Map properties)// 将Map集合中的键值对填充进JavaBean
....
java7的新特性
Map map = (name:"zxx",age:18);
BeanUtils.setProperty(map,"name","lhm");
用BeanUtils类get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。
用PropertyUtils类get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。
去掉JavaBean(ReflectPoint)的public修饰符时,BeanUtils工具包访问javabean属性时出现问题。
------- android培训、java培训、java学习型技术博客、期待与您交流! ----------
本文详细介绍了枚举类型的概念及应用,包括如何用普通类实现枚举,并展示了枚举的具体使用案例。此外,还深入解析了Java内省机制,包括内省的基本概念及其在JavaBean中的应用。
1028

被折叠的 条评论
为什么被折叠?



