黑马程序员 Java高新技术 枚举,内省

本文详细介绍了枚举类型的概念及应用,包括如何用普通类实现枚举,并展示了枚举的具体使用案例。此外,还深入解析了Java内省机制,包括内省的基本概念及其在JavaBean中的应用。

------- 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学习型技术博客、期待与您交流! ----------




内容概要:本文档详细介绍了基于Cplex求解器的风光制氢合成氨系统优化研究,通过Matlab代码实现对这一复杂可再生能源系统的建模与优化分析。研究聚焦于风能、光伏等可再生能源耦合电解水制氢并进一步合成氨的综合能源系统,重点解决系统在容量配置与运行调度方面的协同优化问题。采用Cplex求解器进行高效的混合整数线性规划(MILP)求解,实现了对系统经济性、能效性、环境可持续性的多目标优化,涵盖设备选型与容量设计、能量流分配、运行策略制定、制氢与合成氨工艺集成等关键技术环节。该研究为高比例可再生能源消纳、绿氢规模化生产及绿色化工转型提供了重要的理论依据与可行的技术路径。; 适合人群:具备电力系统、能源系统、运筹学或化工过程系统工程等相关背景,熟悉Matlab编程与数学建模方法,从事新能源、氢能、综合能源系统、绿色化工等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 学习并复现高水平学术论文中关于风光制氢合成氨系统的优化模型构建方法;② 掌握利用Cplex求解器解决复杂能源系统混合整数线性规划(MILP)问题的核心技术与实践流程;③ 为自身的科研项目或工程应用提供系统建模、优化算法实现与代码参考的坚实基础。; 阅读建议:学习者应结合所提供的Matlab代码与相关参考文献,深入剖析模型的物理意义、数学推导过程、约束条件的设定逻辑以及目标函数的设计思路,特别关注Cplex与Matlab的接口调用与数据传递机制,并建议通过调整关键参数(如可再生能源出力、设备效率、成本系数等)进行敏感性分析,以全面理解系统优化的内在机理与决策影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值