JAVA (JavaBean 内省,枚举)
一JavaBean 内省
(1)JavaBean的概念及其理解
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。 这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。
JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。例如:setId、getId,去掉set和get剩下的部分就是属性名,如果剩余 部分的第二个字母是小写的,那么就把剩余部分的首字母改成小写的,如果剩余部分的第二个字母是大写的,那么就让剩余部分的首字母保留大写格式。 例如:setAge,属性名为age。
总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,因为它根本看不到java类内部的成员变量。
我们把一个普通类当作JavaBean使用时会有什么好处呢?
好处如下:
1.在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作。
2.JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。用内省这套api操作JavaBean比用普通类的方式更方便。
(2)内省的简单应用示例
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;
public class IntrospectorTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
//被获取字段的类,即JavaBean
ReflectPoint re = new ReflectPoint(3,4);
//指定要获取的JavaBean类中的相关方法
String propertyName = "x";
Object objget = getProperty(re, propertyName);
System.out.println(objget);
//将要修改的属性的值修改成Value
Object value = 7;
setProperty(re, propertyName, value);
System.out.println(re.getX());
}
private static void setProperty(Object re, String propertyName,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd1 = new PropertyDescriptor(propertyName,re.getClass());
//获取setX()方法
Method methodSetX = pd1.getWriteMethod();
//调用re这个类中的setX()方法将相应的值设置成7
Object objset = methodSetX.invoke(re,value);
}
private static Object getProperty(Object re, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
//用专用的API工具类在re这个类中获取propertyName相关的JavaBean方法
PropertyDescriptor pd = new PropertyDescriptor(propertyName,re.getClass());
//获取getX()方法
Method methodGetX = pd.getReadMethod();
//调用re这个类中的getX()方法
Object objget= methodGetX.invoke(re);
return objget;
}
}
二、枚举
(1)枚举的概念及其理解
枚举:枚举就是要让某个类型的变量取值只能为若干个固定值中的一个,否则编译器就会报错。
枚举的作用:让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式无法在开发阶段实现这一目标。
(2)案例:A:用普通类实现枚举的功能
定义一个Weekday的类来模拟枚举功能
1、私有的构造方法。
2、每个元素分别用一个公有的静态成员变量表示。
3、 可以有若干公有方法或抽象方法。采用抽象方法定义nextDay就将大量的if.else语句转移成了一个个独立的类
方式1
public class WeekDay {
//1、私有化构造方法
private WeekDay(){};
//2、设置固定值
public static final WeekDay MON = new WeekDay();
public static final WeekDay SUN = new WeekDay();
//3、 定义方法操作这些固定的值
public WeekDay nextday()
{
return this==SUN?MON:SUN;
}
//覆盖toString方法查看测试值
public String toString()
{
return this==SUN?"SUN":"MON";
}
}
方式2
public class EnumTest {
public static void main(String[] args) {
WeekDay weekDay=WeekDay.MON;
System.out.println(weekDay.nextDay());
}
}
public abstract class WeekDay {
// 构造方法
private WeekDay() {
}
// 定义周日——周六为静态成员变量,并用内部内实现返回下一天
public final static WeekDay SUN = new WeekDay() {
@Override
public WeekDay nextDay() {
return MON;
}
};
public final static WeekDay MON = new WeekDay() {
@Override
public WeekDay nextDay() {
return TUE;
}
};
public final static WeekDay TUE = new WeekDay() {
@Override
public WeekDay nextDay() {
return WED;
}
};
public final static WeekDay WED = new WeekDay() {
@Override
public WeekDay nextDay() {
return THU;
}
};
public final static WeekDay THU = new WeekDay() {
@Override
public WeekDay nextDay() {
return FRI;
}
};
public final static WeekDay FRI = new WeekDay() {
@Override
public WeekDay nextDay() {
return SAT;
}
};
public final static WeekDay SAT = new WeekDay() {
@Override
public WeekDay nextDay() {
return SUN;
}
};
// 获取一周某一天的下一天的方法
public abstract WeekDay nextDay();
// 打印某个对象值的方法
public String toString() {
String dayName = null;
if (this == SUN) {
dayName = "SUN";
} else if (this == MON) {
dayName = "MON";
} else if (this == TUE) {
dayName = "TUE";
} else if (this == WED) {
dayName = "WED";
} else if (this == THU) {
dayName = "THU";
} else if (this == FRI) {
dayName = "FRI";
} else {
dayName = "SAT";
}
return dayName;
}
}
B:交通灯的枚举类
public class Enum {
public static void main(String[] args)throws Exception {
WeekDay weekDay=WeekDay.MON;
new Date(300){};
}public enum WeekDay{
SUN(32),MON(),TUE,WED,THI,FRI,SAT;
//只要用到这个枚举类,这里面的静态变量都会初始化,
//只要用到了类,它里面的静态代码都会被执行.被执行的时候,
//它里面的构造方法都被调用了
private WeekDay(){System.out.println("first");}
//位于元素列表之后,列表后加分号。
private WeekDay(int day){System.out.println("second");}
//外部类只有两个修饰符,一个是public一个是默认的。
//内部类可以有四个--和成员变量同级。}
public enum TrafficLamp{
RED(30){//red是一个元素,他是由Traffic的子类实现的。
public TrafficLamp nextLamp() {
return GREEN;}
//子类的实现代码,带了抽象方法。
//类里面可以定义静态常量,常量指向的结果就是自己这个类型的实际对象。
} ,GREEN(45){//new子类的实际对象,调用父类的有参的构造方法,
//然后拿GREEN这个名称去引用这个对象。
public TrafficLamp nextLamp() {
return YELLOW;}
},YELLOW(3){
public TrafficLamp nextLamp() {
return RED;}
};//每一个元素都是这个类的实例对象
//RED这个实例不能拿着这个类去new了,只能去找它的子类new,并且名字是RED。
//在哪里去找这个子类:
public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp(int time){this.time=time;} }}
小结:
1,首先枚举本身是一种java类,其基类都是Enum,而Enum继承着Object根类.枚举也是一个抽象类,枚举中可以定义抽象方法.枚举不能被继承不能被程序员创建对象,
因为枚举中的字段和方法不能被复写或修改,所以枚举类是不能被其他类继承的.他就是一个最终类final class. 2,枚举中的字段都是public static final特性,是枚举类本身的类型.每个字段之间有一个","号隔开,最后一个字段后面的","可以省略掉,整个字段的最后要有一
个";"结束符号.如果字段要创建枚举内部类的话就在字段后加上"{}"符号,如果每个对象在创建时要调用含有参数的构造函数,那么可以在字段后"{}"前加"(Object obj)"。