基于Java泛型对Spring中强制类型转换工厂的改进

基于Java泛型对Spring中强制类型转换工厂的改进
基于Java泛型对Spring中强制类型转换工厂的改进

https://www.360docs.net/doc/b113336528.html,
基于 Java 泛型对 Spring 中强制类型转换工厂的改进
苗锡奎
辽宁工程技术大学电子与信息工程学院,辽宁葫芦岛(125105)
E-mail:miaoxikui@https://www.360docs.net/doc/b113336528.html,
摘 要: 本文主要利用泛型编程将泛型机制与设计模式有机的结合并加以优化和实现, 提出 一种提出利用了 Java 的新特性—泛型类型(generic type),在工厂设计模式或其它应用中 摆脱类类型在强制转换或向下类型转换的过程中极容易发生的错误的设计方案。并针对 Spring 中的强制类型转换的工厂进行了改进, 在利用工厂获得某个类的实例时不需要硬编码 的方式强制转换实例的类型。 关键词:泛型,泛型编程,工厂模式,XML 中图分类号:TP311
1. 引言
软件的解耦一直是软件研究领域的一个热点课题。 所产生的思想也数不胜数, 其中的两 大重要思想是 Ioc 思想和 Aop 思想, 然而这些思想都是种种设计模式的体现。 其中的工厂设 计模式就在这两种思想中都有所体现。然而工厂模式虽然优势很多但是也存在着不足之处。 在面向对象设计的软件中我们与软件打交道的无疑都是一个个的对象, 而且一个软件的 灵活性是与软件的整个软件的体系结构设计的好坏有直接的关系。 而如何井井有条地产生与 组织对象就变的首当其冲了。工厂模式中的简单工厂模式是有效产生和管理对象的有利工 具。 在软件的体系结构设计过程中为了达到软件功能的解耦常常利用设计模式对软件进行建 设。工厂方法就是解耦的一种有效的途径。在 Spring 中就应用了大量的工厂方法,它可以 通过配置文件的配置信息来得到某个类的实例[1]。 而不用通过硬编码的方式如 A a = new A () 来产生对象, 使对象与产生对象的类之间在程序中观察不出任何的联系来。 无论是采用面向 接口方式编程来使软件的解耦程度更上一层楼还是直接面向类编程, 利用工厂方法都必须在 对象显示产生的时候为其强制指定某种类型,这不仅为程序的编写者带来了不必要的麻烦, 而且在一定的程度上改善了软件体系结构的可扩展性。 Java 是一种强类型的语言, Java 的安全和健壮性部分来自于它是该类型语言这一事实。 Java 编译器对所有的表达式和参数都要进行类型相容性的检查以保证类型是兼容的。任何 类型的不匹配都是错误的,在编译器完成编译以前,错误必须被改正。例如我们有抽象类 A 和其实现类 AA 或接口 B 和其实现类 BB,利用 Spring 的工厂产生类 BB 的实例的时候就必 须写成如下格式: a = (BB)BeanFactory.getBean(“bb”);当然这仅仅是类型转换的一种。 A 这就 要求程序员必须严格的遵守这一规则, 当然遵守这一规则带来的安全性和健壮性要远远大于 不遵守这一规则所带来的方便性。 但是我们可以在特定的环境下, 利用泛型机制将这一规则 所带来的约束降低到最小。 基于以上存在的问题, 提出了可以在程序运行过程中动态的产生对象并不用强制为其指 定类型的一种可行的设计方案。
2. 方案介绍
2.1 简单工厂模式简介
在工厂模式的简单工厂模式中, 工厂处于对产品类进行实例化的中心位置上, 它知道每 一个产品类的细节, 并决定在何时哪一个产品类应当被实例化。 实质上就是由一个工厂类根
-1-

https://www.360docs.net/doc/b113336528.html,
据传入的参量决定创建出哪一种产品的实例。 可以用一个示意性的图来表示简单工厂模式的 结构。
图 2.1 简单工厂模式的结构图
简单工厂模式的优点是能够使客户端独立于产品的创建过程, 并且在系统中引入新产品 时无需对客户端进行修改,缺点是当有新产品要加入到系统中时,必须对工厂类进行修改, 以加入必要的处理逻辑。 简单工厂模式的致命弱点就是处于核心地位的工厂类, 因为一旦它 无法确定要对哪个类进行实例化时,就无法使用该模式[2]。
2.2 方案简介
针对 2.1 中所述的简单工厂模式的原理即是根据传入的参量决定创建出哪一种产品的实 例和其致命弱点,我们可以从传入的“参量”为突破口结合 Java 泛型机制,利用 Apache 的 Commons Digester 组件来有效合理的组织配置文件, 从而实现工厂根据系统的配置文件的不 同参量来产生不同类的实例。 其过程可以详述为: 系统读取按照一定格式设计的配置文件中 的参量, 然后把此参量所携带的信息进行进一步的加工和提取, 最后把它转换成与配置文件 的配置项相对应的对象,工厂利用该对象所携带的信息利用泛型产生与该信息相对应的实 例。Commons Digester 组件的工作原理不是本文所介绍的重点,故未详细叙述,可以参考有 关文档。 这样不但可以有效的改进简单工厂模式的缺点使该模式在当有新产品要加入到系统 中时不必修改处于核心地位的工厂类, 而且可以为程序的编写者摆脱类类型在强制转换或向 下类型转换的过程中极容易发生的错误所带来的不便和使软件的解耦性。 该方案可以形象地 解释成“工厂根据配置文件的信息产生对象,该对象就可以直接的赋值给抽象的引用、接口 的引用或类的引用,而不用对其进行强制类型的转换”。
3.方案的设计
3.1 配置文件格式的定义
由于该方案是模拟从配置文件中读取将要生产的“产品”的信息,因此十分有必要对“产 品”所表示的信息格式化,工厂可以可以根据不同的参量或者配置信息得到不同的“产品”, 进而实现了“产品对象”的可配置性。如果要增加新的“产品”,就可以在配置文件中填加,无 须对工厂类进行修改。 在这个方案中,是通过采用 XML 配置文件的方式来实现“产品”信息的封装。工厂在生 产“产品”的时候通过 Digester 组件将 XML 配置项(产品信息)转换成相应的对象的,以便可 以得到各种关于该“产品”的所有有用的信息,工厂就是利用这个信息来生产“产品”的。 为使本方案的设计与实现达到“不相对复杂化”,并且与 Spring 配置文件进行对比之后 决定采用如下格式的配置文件:
-2-

https://www.360docs.net/doc/b113336528.html,
……… 考虑到本文所将要实现的重点并不是在此,而是仅仅用 product 节点元素模拟某个产品 应该有的一些信息, 而不至于使方案的设计和实现复杂化。 当然读者完全可以根据自己的业 务需求和业务模型相应地为“产品”的填加必要信息,这完全不是技术难题了。故在此也为给 出 configuration、products 两个节点元素的基本信息,并且也没有给出该 XML 配置文件的 DTD 文件。 配置文件的格式一目了然,根元素 configuration 表示这是一个全局的配置信息。在 configuration 元素内包含了一个 products 元素,这就是“产品”配置信息的集合。Products 元 素所包含的每一个 product 元素就代表了一个基本的“产品”信息。 下面给出 product 节点元素 详细的说明: id:产品的唯一标识。 type:与产品相对应的产品类。 single:表示在由工厂生产该产品时,是否是全局唯一。single=”true”:表示工厂生产的 某种产品只有一个产品实例,single=”false”: 表示工厂生产的某种产品的产品实例个不相 同。single 默认为 true。 argsi:i=0,1,2….表示该产品的构造方法的参数。本方案只考虑了字符串类型的参数, 若要扩展可以自行填加。 根据 Digester 组件的工作原理,需要定义与节点元素相应的类。 Configuration 类和 Product 类分别与 configuration 和 product 节点元素对应,其实现见后文。
3.2 方案的类图
类图是用于对系统的静态设计视图建模[3],所以该方案是用类图来说明其静态的结构。 根据上述方案所存在的类、属要及方案实现的功能,可以给出该方案的静态结构。由于方案 的设计是通用的所以对面向接口变成还是面向类编程或是面向抽象编程了产品对该方案的 实现都无影响,因此对产品的类并没有做设计。
-3-

https://www.360docs.net/doc/b113336528.html,
图 3.2 方案的类图
3.3 方案的时序图
时序图描述了以时间顺序组织的对象之间的交互活动[3], 因此本方案采用时序图来描述 其行为。可以根据类之间的交互可以很容易地分析类中应该有那些责任(方法),进而在实现 方案的时候完善类中的方法。
图 3.3 方案的时序图
-4-

https://www.360docs.net/doc/b113336528.html,
3.4 方案的优化设计
程序质量的好坏直接影响了程序的执行速度,因此对方案的优化十分必要。 3.4.1 读取配置文件的工具类的优化 在工厂生产产品的时候主要是根据配置文件的信息来产生的, 因此在设计读取配置文件 的类的时应该考虑通过一个静态的 Configuration 类的实例来保存解析后的根配置对象。之 所以这样做是因为在这个工具类中生成的根配置对象应该是全局唯一的且面向大众共享的。 同时解析配置文件的规则和对象的生成代码都应该放到静态代码块中, 从而保证该代码块只 在该工具类加载的时候执行一次, 其它时候都不会执行。 次这样就不需要在每次读取配置文 件的时候重新进行解析操作。 3.4.2 工厂类和产品类的优化 该工厂可以达到在程序中动态的根据参量的不同来获取类的信息 (如构造方法, 方法和 方法的参数等) 来产生不同的对象。 而该对象的类型就完全可以不加强制类型转换直接赋给 是声明的引用。首先在工厂中能够直接获得产品的配置项对象的信息,而把生产“产品”的具 体任务仍然交给产品本身,这体现了类的封装性,提高了模块的内聚性。 在产品类中引入了一个工具类 CreateProductUtil 来辅助产品类,以使产品类更加简单。 之所以在这里就生成对象的实例,主要是出于对运行效率的考虑。在这里可以根据 single 的 值和构造方法的参数来生成符合要求的实例。
4.方案的实现
在对方案的静态视图和动态视图分析了之后, 就可以对方案的类图做进一步的细化, 即 可以对类进行编码了。
4.1 方案的构件图
构件图展现了构件之间的组织与依赖, 而组件是开发和运行时的物理对象的类, 它专注 于系统的静态实现[4]。因此用构件图可以很清楚的展现案的静该方态实现。
图 4.1 方案的构件图
4.2 配置项类的实现
根据配置文件的格式和节点元素,本方案只实现了 configuration 和 product 两个节点元
-5-

https://www.360docs.net/doc/b113336528.html,
素的配置类,分别为 Configuration 和 Product。在这里没有实现 products 节点元素的配置类, 主要原因是 products 元素的作用只是将 product 元素封装起来,本身没有任何属性。但 Configuration 是整个 XML 文件的根元素,在生成 Java 对象后,将是所有子元素的的容器。 另外如果 configuration 还可能在将来加入其它子元素, 可以在方案扩展的时候使配置文件结 构上更加清晰一些。类中的成员和方法可以参见类图,可以很容易根据 Java 的语法写出类 文件[5]。
4.3 其它类的实现
CreateFactory、ConfigurationUtil、CreateProductUtil 分别是工厂类、读取配置文件的工 具类、产品的辅助类。根据上文的类图可以确定类所拥有的基本的成员,而根据时序图可以 很容易地确定出类中需要增加的交互功能的成员,最终形成类文件。
5.结论
该方案对简单工厂模式采用了读取配置文件方式来获得“产品”的信息之后, 利用泛型机 制来在程序运行过程中动态地根据不同的参量产生对象, 使得在由工厂获得“产品”的时候相 对传统的简单工厂模式有了很大的改进, 使得获得的“产品”没有必要进行类型的转型就可以 赋给声明的变量。同时由于配置文件的存在,增加“产品”的种类时不用修改工厂类, 体现了软件设计的“开—闭原则”即对扩展开放,对修改关闭。但在 Spring 的工厂中,当生 产“产品”时必须进行类型的转换才能赋给声明的变量, 这在程序员十分熟悉程序的情况下增 加了编程的复杂性。不加强制类型转换直接赋给是声明的引用。当然是有一定的好处的,同 时也会有一定的弊端的, 这主要取决于该方案的应用环境了, 如果在特定的应用条件下注重 编程的简单性和灵活性则利大于弊。 由于该方案只是对这种思想的简单实现,故在在 product 节点元素没有足够多的信息来 反映该“产品”,其动态获取类的详细信息也是相当复杂的工程,还需要更大的努力,这也是 下一步研究的重点。
参考文献
[1] 郭锋.Spring 从入门到精通(第 1 版),北京:清华大学出版社,2006.10。 [2] 阎宏.java 与模式(第 1 版),北京:电子工业出版社,2002.10。 [3] (美)巴拉赫,(美)兰宝 著,车皓阳,杨眉 译.UML 面向对象建模与设计(第 2 版),北京:人民邮电出 版社,2006.01 [4] 吴建,郑潮,汪杰.UML 基础与 Rose 建模案例(第 1 版), 北京:人民邮电出版社,2004.10。 [5] (美)Bruce Eckel.Java 编程思想(第 3 版),北京:机械工业出版社,2004.01。
-6-

https://www.360docs.net/doc/b113336528.html,
Improvements Of The Mandatory ClassCast BeanFactroy In Spring Based on Java Generic
Miao Xikui
Electronics and Information Engineering Department,Liaoning Technical University,Huludao, Liaoning (125105) Abstract
This paper mainly use the organic integration of Generic Programming and Design Patterns mechanism and realize them optimally, A proposal used the new features of Java - Generic types, getting rid of errors in the factory design pattern or other types of applications,which use the class cast. Against the mandatory classcast beanfactory in Spring ,Some improvements are made, not requiring through hard code of the mandatory classcast when get a instance of Class from factory. Keywords:Generic,Generic Programming,Factory Pattern,XML
作者简介:苗锡奎,男,硕士研究生,主要研究方向为机软件工程。
-7-

java对象转换String类型的三种方法

北大青鸟中关村 java对象转换String类型的三种方法在很多情况下我们都需要将一个对象转换为String类型。一般来说有三种方法可以实现:Object.toString()、(String)Object、String.valueOf(Object)。下面对这三种方法一一分析 一、采用Object.toString() toString方法是https://www.360docs.net/doc/b113336528.html,ng.Object对象的一个public方法。在java中任何对象都会继承Object 对象,所以一般来说任何对象都可以调用toString这个方法。这是采用该种方法时,常派生类会覆盖Object里的toString()方法。 但是在使用该方法时要注意,必须保证Object不是null值,否则将抛出NullPointerException 异常。 二、采用(String)Object 该方法是一个标准的类型转换的方法,可以将Object转换为String。但是在使用该方法是要注意的是需要转换的类型必须是能够转换为String的,否则会出现CalssCastException异常错误。 代码代码如下: Object o = new Integer(100); String string = (String)o; 这段程序代码会出现https://www.360docs.net/doc/b113336528.html,ng.ClassCastException: https://www.360docs.net/doc/b113336528.html,ng.Integer cannot be cast to https://www.360docs.net/doc/b113336528.html,ng.String。因为将Integer类型强制转换为String类型,无法通过。 三、String.valueOf(Object) 上面我们使用Object.toString()方法时需要担心null问题。但是使用该方法无需担心null值问题。因为在使用String.valueOf(Object)时,它会判断Object是否为空值,如果是,则返回null。下面为String.valueOf(Object)的源码: 代码代码如下: public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } 从上面我们可以看出两点:一是不需要担心null问题。二是它是以toString()方法为基础的。但是一定要注意:当object为null时,String.valueOf(object)的值是字符串对象:"null",而不是null!!!

《集合框架及泛型》上机实践内容

《集合框架及泛型》作业 一、根据课上讲解内容,完成演示示例和课堂练习 1、ArrayList获取并打印新闻标题 需求说明:按照以下实现的步骤,使用ArrayList获取和打印新闻标题,显示效果如下图所示: (1)创建多个各类新闻标题对象,包含ID、名称和创建者三个属性; (2)创建存储各类新闻标题的集合对象; (3)按照顺序依次添加各类新闻标题,使用add()方法; (4)获取新闻标题的总数,使用size()方法; (5)根据位置获取相应新闻标题、逐条打印每条新闻标题的名称,使用for 循环遍历。 2、ArrayList存储狗狗信息 需求说明:按照以下实现的步骤,使用ArrayList存储狗狗信息,使用ArrayList的方法对狗狗信息进行删除、读取和判断,显示效果如下图所示:(1)存储多条狗信息,获取狗总数,逐条打印出各条狗信息; (2)删除指定位置的狗,使用remove()方法; (3)判断集合中是否包含指定狗,使用contains()方法;

3、LinkedList添加和删除新闻标题 需求说明:在作业1的基础上,换用LinkedList存储新闻数据,并且使用LinkedList的getFirst()和getLast()方法获取第一条和最后一条数据,以及removeFirst()和removeLast()方法删除第一条和最后一条数据,输出效果如下图所示。 4、集合头尾位置删除和条件狗信息 需求说明:按照作业3的实现方式和所用到LinkedList的方法,实现狗狗信

息的更新并输出,输出效果如图所示。 5、使用Iterator和增强型for循环遍历Set 需求说明:按照以下实现的步骤,使用Iterator和增强型for循环遍历Set,输出效果如下图所示: (1)创建多个各类新闻标题对象,包含ID、名称和创建者三个属性; (2)创建存储各类新闻标题的集合对象; (3)按照顺序依次添加各类新闻标题; (4)获取新闻标题的总数; (5)使用iterator()获取Iterator对象; (6)使用Iterator遍历集合,使用hasNext()方法作为循环条件,判断是否存在另一个可访问的元素; (7)使用增强型for遍历集合;

JAVA的各种变量类型的转换

JAVA的各种变量类型的转换 1 如何将字串 String 转换成整数 int? A. 有两个方法: 1).int i = Integer.parseInt([String]); i = Integer.parseInt([String],[int radix]); 2). int i = Integer.valueOf(my_str).intValue(); 注: 字串转成 Double, Float, Long 的方法大同小异. 2 如何将整数 int 转换成字串 String ? A. 有叁种方法: 1.) String s = String.valueOf(i); 2.) String s = Integer.toString(i); 3.) String s = "" + i; 注: Double, Float, Long 转成字串的方法大同小异. java的各种变量类型的转换 integer to String : int i = 42; String str = Integer.toString(i); String str = "" + i double to String : String str = Double.toString(i); long to String : String str = Long.toString(l); float to String : String str = Float.toString(f); String to integer : str = "25";

int i = Integer.valueOf(str).intValue(); int i = Integer.parseInt(str); String to double : double d = Double.valueOf(str).doubleValue(); String to long : long l = Long.valueOf(str).longValue(); long l = Long.parseLong(str); String to float : float f = Float.valueOf(str).floatValue(); decimal to binary : int i = 42; String binstr = Integer.toBinaryString(i); decimal to hexadecimal : int i = 42; String hexstr = Integer.toString(i, 16); String hexstr = Integer.toHexString(i); hexadecimal (String) to integer : int i = Integer.valueOf("B8DA3",16).intValue(); int i = Integer.parseInt("B8DA3", 16); ASCII code to String int i = 64; String aChar = new Character((char)i).toString(); integer to ASCII code (byte) char c = 'A'; int i = (int) c; To extract Ascii codes from a Strin String test = "ABCD"; for ( int i = 0; i < test.length(); ++i ) {

C语言中的强制类型转换运算

C语言中的强制类型转换运算 C语言中的强制类型转换是通过类型转换运算来实现的。 其一般形式为: (类型说明符)(表达式) 其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。 例如: (float)a 把a转换为实型 (int)(x+y)把x+y的结果转换为整形 在使用强制转换时应注意以下问题: 1)类型说明符和表达式都必须加括号(单个变量可以不加括号),如果把(int)(x+y)写成(int)x+y则成了把x转换成int型之后再与y相加了。 2)无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性的转换,而不改变数据说明时对该变量定义的类型。 【例1】 #include int main (void) { float f = 3.14; printf("(int)f = %d,f = %.2f\n",(int)f,f); return 0; } 本例表明,f虽强制转为int型,但只在运算中起作用,是临时的,而f本身的类型并不改变。因此,(int)f的值为5(删去了小数)而f的值仍为5.75. 1、求余运算符(模运算符)“%”:双目运算,具有左结合性。要求参与运算的量均为整型。求余运算的结果等于两数相除后的余数。 #include int main (void) { printf(" %d\n",110%3);

return 0; } 本例输出110除以3所得的余数2。 2、算数表达式和运算符的优先级和结合性 表达式是由常量、变量、函数和运算符组合起来的式子。一个表达式有一个值及其类型,他们等于计算表达式所得结果的值和类型。表达式求值按运算符的优先级和结合性规定的顺序进行。单个的常量、变量、函数可以看作是表达式的特例。 算数表达式是由算术运算符和括号连接起来的式子。 算数表达式:用算数运算符和括号将运算对象(也称操作数)连接起来的、符合C语法规则的式子。 以下是算数表达式的例子: a+b; (a*2)/c; (x+r)*8-(a+b)/7; ++I; Sin(x)+sin(y); (++i)-(j++)+(k--); 运算符的优先级:C语言中,运算符的运算优先级共分为15级。1级最高,15级最低。在表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。 运算符的结合性:C语言中各运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。例如算术运算符的结合性是自左至右,即先左后右。如有表达式x-y+z,则先执行x-y运算,然后再执行+z运算。这是左结合性。右结合性最典型的是赋值运算符。如x=y=z. 3、强制类型转换运算符 其一般形式为: (类型说明符)(表达式)

实验十 泛型与集合框架

实验十泛型与集合框架 1.实验目的 1、掌握LinkedList类和Collections类提供的用于排序和查找链表中 的数据的方法 2、掌握用散列映射来存储数据 3、掌握TreeSet类的使用 2.实验内容 1、根据附录里的源代码,按照注释要求,完成代码填空,使程序能够运行 得出结果。 1)实验1 按身高排序 2)实验2 英汉小字典 3)实验3 演出节目单 4)实验4输出args[]中的单词 2、设计编写程序完成以下任务。 1)仿照实验1编写TV类,要求通过实现Comparable接口规定该类的对象的大小关系,按price值得大小确定大小关系,即电视机按其价格确定之间的大小关系。 2)从控制台输入若干个单词(输入回车结束)放入集合中,将这些单词排序后(忽略大小写)打印出来。 知识点:List接口的实现类、String常用方法 3)请使用LinkedList来模拟一个队列(先进先出的特性): (1)拥有放入对象的方法void put(Object o) (2)取出对象的方法Object get() (3)判断队列当中是否为空的方法boolean isEmpty();并且,编写测试代码,验证你的队列是否正确。 知识点:List接口的实现类LinkedList常用方法 4)在一个列表中存储以下元素:apple,grape,banana,pear (1)返回集合中的最大的和最小的元素 (2)将集合进行排序,并将排序后的结果打印在控制台上 知识点:Collections类中的方法 3.实验步骤 略 4.评分标准 1.A——内容功能完善,编程风格好,人机接口界面好; 2.B——内容功能完善,编程风格良好,人机接口界面良好;

强制类型转换及指针本质

强制类型转换类型的本质指针的本质函数指针 昨天给朋友讲了 3个问题, A〉什么是函数指针,本质是?指针的本质? B〉什么是类型,类型的本质是? C〉什么是强制类型转换,本质是? 作者张世光亿通科技软件部 060913 QQ:87895224 MSN:Z_55@https://www.360docs.net/doc/b113336528.html, A〉什么是函数指针,本质是?指针的本质? 如 void fun(); //函数声明 void (*ptrfun)();//函数指针变量ptrfun 的声明,表明ptrfun这个指针指向一个 void fun()函数类型的函数地址。 〉函数的名字代表函数的地址; 所以,可以这样 ptrfun =fun ;//给ptrfun赋值。此时,ptrfun 就是 fun 函数的别名; 在需要调用 fun()的地方,可以这样写 (*ptrfun)(); //等同于 fun(); //这就是别名的意义。 指针的本质是一个固定长度(32位系统上是4个byte)的空间中放置的内容是一个内存地址。 而指针类型的本质就是对这个地址的解释方式。不同的指针类型,对即使相同的内存地址的解释是不同的,受影响的空间大小也不同。受影响的空间的大小等于sizeof(类型)。 如 short i=0x1234; short * psort = &i; char *pchar = &i; //此时 pshort ==pchar;即指向了同一个地址; 那么 (*pshort) 和 (*pchar) 的值各是什么? 假设 sizeof(short)==2 sizeof(char)==1 假如内存中这样: ---地址 0x1000-- | 0x34 | ---------------- | 0x12 | ---------------- 那么,psort==0x1000 ,同时,pchar==0x1000 ; 那么,(*psort) 代表是地址0x1000 和 0x1001 这两个字节的内容; <-----由其类型决定 (*pchar)代表地址0x1000 这一个字节的内容; <<-----由其类型决定

Java中常见异常类型及分析

Java常见异常类型及原因分析 这里介绍几种常见的异常并对原因进行分析,包括: ●NullPointException异常; ● ClassCastException异常; ● ArrayIndexOutOfBoundsException异常; ●UnsupportedClassVersionError错误; ●NumberFormatExceptio异常 ●堆栈溢出和内存溢出。 1 NullPointException异常 顾名思义,NullPointerException是空指针异常。但是在Java中没有指针,怎么会有空指针异常呢? 在C++中,声明的指针需要指向一个实例(通过new方法构造),这个指针可以理解为地址。 在Java中,虽然没有指针,但是有引用(通常称为对象引用,一般直接说对象),引用也是要指向一个实例对象(通过new方法构造)的,从这种意义上说,Java中的引用与C++中的指针没有本质的区别,不同的是,处于安全的目的,在Java中不能对引用进行操作,而在C++中可以直接进行指针的运算,例如book++等。 所以这里的NullPointerException虽然不是真正的空指针异常,但本质上差不多,是因为引用没有指向具体的实例,所以当访问这个引用的方法的时候就会产生这种异常。例如下面的代码: String str = "这是一个测试用的字符串!"; System.out.println(str.length()); 这段代码没有问题,但是如果改成下面的代码: String str ; System.out.println(str.length()); 就会产生NullPointerException异常了,当然一般人不会犯这样低级的错误。 那这种异常通常是如何产生的呢?比较多见的是下面的两种情况: 1)把调用某个方法的返回值直接赋值给某个引用,然后调用这个引用的方法。在这种情况下,如果返回的值是null,必然会产生NullPointerException异常。例如: String userName=request.getParameter("userName"); if(userName.length()==0) ...... else ...... 如果request.getParameter("userName")的结果为null,则这里就会产生这种异常。 2)在方法体中调用参数的方法。这种情况下,如果调用方法的时候传递进来的值是null,也要产生NullPointerException异常。 要解决这种异常,只需要检查异常出现在第几行(通常在集成开发环境中会提示用户错误发生在第几行),然后查看调用了哪个对象的方法,然后检查这个对象为什么没有赋值成

java的基本数据类型有八种

java的基本数据类型有八种 各位读友大家好!你有你的木棉,我有我的文章,为了你的木棉,应读我的文章!若为比翼双飞鸟,定是人间有情人!若读此篇优秀文,必成天上比翼鸟! java的基本数据类型有八种四类八种基本数据类型1. 整型byte(1字节)short (2个字节)int(4个字节)long (8个字节)2.浮点型float(4个字节)double(8个字节)3.逻辑性boolean(八分之一个字节)4.字符型char(2个字节,一个字符能存储下一个中文汉字)基本数据类型与包装类对应关系和默认值short Short (short)0int Integer 0long Long 0Lchar Char '\u0000'(什么都没有)float Floa t0.0fdouble Double 0.0dboolean Boolean false 若某个类的某个成员是基本数据类型,即使没有初始化,java也会确保它获得一个默认值,如上所示。(这种初始化方法只是用于成员变量,不适用于局部变量)。jdk1.5支持自动拆装箱。可以将基本数据类型转换成它的包装类装箱Integer a = new Integer ();a = 100;拆箱int b = new Intger(100);一个字节等于8位,一个字节等于256个数,-128到127一个英文字母或一个阿拉伯数字就是一个字符,占用一个字节一个汉字两个字符,占用两个字节基本数据类型自动转换byte->short , char->int->longfloat->doubleint ->floatlong->double小可转大,大转小会失去精度。字符串与基本类型或其他类型间的转换⑴其它

C++强制类型转换

关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的《C++ 的设计和演化》。最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast, dynamic_cast。标准C++中有四个类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast。下面对它们一一进行介绍。 static_cast 用法:static_cast < type-id > ( expression ) 该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法: ?用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。 ?用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。 ?把空指针转换成目标类型的空指针。 ?把任何类型的表达式转换成void类型。 注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。 dynamic_cast 用法:dynamic_cast < type-id > ( expression ) 该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;如果type-id是类指针类型,那么expression也必须是一个指针,如果ty pe-id是一个引用,那么expression也必须是一个引用。 dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

简析JAVA中int、String间类型转换

初学Java,对于类型转换以及强制类型转换还是没什么难度的,但是初学者往往在涉及到String类型的转换时,就会抛出问题了。这里收集整理了下,仅供参考。 int 转String int i=12345; String s=”"; 第一种方法:s=i+”"; 第二种方法:s=String.valueOf(i); 这两种方法有什么区别呢?作用是不是一样的呢?是不是在任何下都能互换呢? String转int s=”12345″; int i; 第一种方法:i=Integer.parseInt(s); 第二种方法:i=Integer.valueOf(s).intValue(); 这两种方法有什么区别呢?作用是不是一样的呢?是不是在任何下都能互换呢? 以下是答案:

3.) String s = “” + i; 注: Double, Float, Long 转成字串的方法大同小异. JAVA数据类型转换这是一个例子,说的是JAVA中数据数型的转换.供大家学习package shenmixiaozhu; import java.sql.Date; public class TypeChange { public TypeChange() { } //change the string type to the int type public static int stringToInt(String intstr) { Integer integer; integer = Integer.valueOf(intstr); return integer.intValue(); } //change int type to the string type public static String intToString(int value) { Integer integer = new Integer(value); return integer.toString(); } //change the string type to the float type public static float stringToFloat(String floatstr) { Float floatee; floatee = Float.valueOf(floatstr); return floatee.floatValue(); } //change the float type to the string type public static String floatToString(float value) { Float floatee = new Float(value); return floatee.toString(); } //change the string type to the sqlDate type public static java.sql.Date stringToDate(String dateStr) { return java.sql.Date.valueOf(dateStr); } //change the sqlDate type to the string type

JAVA实验报告-集合框架与泛型机制

Java 语言程序设计 C 实验报告 集合框架及泛型机制 学生姓名 专业、班级 指导教师 成绩 计算机与信息工程学院 年月日

一、实验目的 学习课程相关章节知识,通过上机练习,掌握以下知识: 1.掌握 List 接口下 ArrayList 及 LinkedList 的使用方法。 2.掌握 Map 接口下 HashMap 及 HashTable的使用方法 3.掌握集合中泛型的使用 二、实验内容 利用集合完成象数据库那样存储数据,并且可以简单查询,利用 map 存储学生信息,字段如下: id ,name,age,实现步骤: (1)创建类,类图如下: (2)在 main 方法编写逻辑代码 (3)运行程序并测试结果 package https://www.360docs.net/doc/b113336528.html,; public class Student { private String name ; private int age ; private String id ;

public String getName() { return name ; } public void setName(String name ) { this . name =name ; } public int getAge() { return age ; } public void setAge(int age ) { this. age=age ; } public String getId() { return id; } public void setId(String id) { this. id=id; } public Student(String name ,int age , String id ) { super(); this. name =name ; this. age=age ; this. id=id; } public void sayHi() { System.out.println("name=" +this.getName()+"age=" + this .getAge()+" " + "id=" + this.getId()); } }

Java语言基本数据类型、转换及其封装

Java语言基本数据类型、转换及其封装Java语言基本数据类型、转换及其封装 1. 逻辑类型 ·常量 true,false。 ·变量的定义 使用关键字boolean来定义逻辑变量: boolean x; boolean tom_12; 也可以一次定义几个: boolean x,tom,jiafei,漂亮 x,tom,jiafei,漂亮都是变量的名字。定义时也可以赋给初值: boolean x=true,tom=false,漂亮=true,jiafei 2.整数类型 ·常量123,6000(十进制),077(八进制),0x3ABC(十六进制)。 ·整型变量的定义分为4种: 1.int 型 使用关键字int来定义int型整形变量 int x int tom_12 也可以定义几个: int x,tom,jiafei,漂亮 x,tom,jiafei,漂亮都是名字。定义时也可以赋给初值: int x=12,tom=-1230,漂亮=9898,jiafei 对于int型变量,分配给4个字节byte,一个字节由8位(bit)组成,4个字节占32位(bit)。bit 有两状态,分别用来表示0,1。这样计算机就可以使用2进制数来存储信息了。内存是一种特殊的电子元件,如果把内存条放大到摩天大

楼那么大,那么它的基本单位——字节,就好比是大楼的房间,每个房间的结构都是完全相同的,一个字节由8个能显示两种状态的bit组成,就好比每个房间里有8个灯泡,每个灯泡有两种状态——亮灯灭灯。 对于 int x=7; 内存存储状态如下: 00000000 00000000 00000000 00000111 最高位:左边的第一位,是符号位,用来区分正数或负数,正数使用原码表示,最高位是0,负数用补码表示,最高位是1。例如: int x=-8; 内存的存储状态如下: 11111111 11111111 11111111 11111000 要得到-8的补码,首先得到7的原码,然后将7的原码中的0变成1,1变成0,就是-8的补码。 因此,int型变量的取值范围是-2^31~2^31-1。 2. byte型 使用关键字byte来定义byte型整型变量 byte x ; byte tom_12; 也可以一次定义几个: byte x,tom,jiafei,漂亮 x,tom,jiafei,漂亮都是名字。定义时也可以赋给初值: byte x=-12,tom=28,漂亮=98,jiafei 注:对于byte型变量,内存分配给1个字节,占8位,因此byte型变量的取值范围是: -2^7~2^7-1。

int.parse和强制类型转换的区别

c#中(int)、int.Parse()、int.TryParse、Convert.ToInt32的区别收藏 以前经常为这几种数据类型转换方式而迷茫,这次为了彻底搞清它们之间的区别和优缺点,在网上查看了一些资料,并亲自验证了一下,在此写出来,一方面,为那些跟我有过相似经历的朋友们些许,另一方面,希望前辈们指导一下,看哪里有不合适的地方。 1 (int)变量名[强制类型转换]: 该转换方式主要用于数字类型转换,从int类型到long,float,double,decimal类型,可以使用隐式转换,但是从long类型到int类型就需要使用显式转换,也就是该数据类型转换方式,否则会产生编译错误。 该方式对于浮点数会做无条件舍去,失去精确度 当然,该方式也可以进行object到int得转换,但是,object的值要赋予int类型的值,否则会产生编译错误,而且object为null时也会出错。 最后切忌的一点,千万不要用来处理char类型到int类型的转换,否则传回的的值是ASCII代码,而并不是你想要的值。 2 int.Parse(string类型变量名) 该方式是将数字内容的字符串转为int类型,如果字符串内容为空或者null时,则抛出ArgumentNullException异常;如果字符串内容不是数字,则抛出FormatException异常;如果字符串内容所表示数字超出int类型可表示的范围,则抛出OverflowException异常。 使用该方法切忌的一点就是只能处理字符串内容,而且字符串内容只能在int类型可表示的范围之内。 3 int.TryParse(string s, out int result) 该方式也是将数字内容的字符串转为int类型,但是该方式比int.Parse优越的地方,就是它不会出现异常。如果转换成功返回true,如果转换失败返回false。很明显,最后一个参数为输出值,如果转换失败,输出值为0;如果转换成功,则输出相应的值。 4 Convert.ToInt32 该方式不仅可以将字符串转为int类型,还可以将其它类型的值转成int类型。变量若为object或string类型,当其值为null时,会传回0,不会造成程序错误,但是若此string类型的值为string.Empty,在转型成int时,仍会造成程序错误。 该方式对于浮点数会做四舍五入。 该方式同强制转换一样,不能用来处理char类型,否则传回的是ASCII代码。

JAVA实验报告-集合框架及泛型机制

Java语言程序设计C 实验报告 集合框架及泛型机制 学生姓名 专业、班级 指导教师 成绩 计算机与信息工程学院 年月日 一、实验目的 学习课程相关章节知识,通过上机练习,掌握以下知识:

1.掌握List接口下ArrayList及LinkedList的使用方法。 2.掌握Map接口下HashMap 及HashTable的使用方法 3.掌握集合中泛型的使用 二、实验内容 利用集合完成象数据库那样存储数据,并且可以简单查询,利用map存储学生信息,字段如下: id ,name,age,实现步骤: (1)创建类,类图如下: (2)在main方法编写逻辑代码 (3)运行程序并测试结果 package com、cn; public class Student { private String name; private int age; private String id; public String getName() { return name; } public void setName(String name) {

this、name = name; } public int getAge() { return age; } public void setAge(int age) { this、age = age; } public String getId() { return id; } public void setId(String id) { this、id = id; } public Student(String name, int age, String id) { super(); this、name = name; this、age = age; this、id = id; } public void sayHi() { System、out、println("name="+this、getName()+"age="+this、getAge()+" "+"id="+this、getId()); } } //Databace类 package com、cn; import java、util、Collection; import java、util、HashMap; import java、util、Iterator; public class Databace { private Student a; public Databace() { super(); map=new HashMap(); } public Student getA() { return a; }

Java数据类型转换:强制类型转换 自动类型转换28

数据类型的转换是在所赋值的数值类型和被变量接收的数据类型不一致时发生的,它需要从一种数据类型转换成另一种数据类型。数据类型的转换可以分为隐式转换(自动类型转换)和显式转换(强制类型转换)两种。 隐式转换(自动类型转换) 如果以下 2 个条件都满足,那么将一种类型的数据赋给另外一种类型变量的时,将执行自动类型转换(automatic type conversion)。 ?两种数据类型彼此兼容 ?目标类型的取值范围大于源数据类型(低级类型数据转换成高级类型数据) 当以上 2 个条件都满足时,拓宽转换(widening conversion)发生。例如 byte 类型向 short 类型转换时,由于 short 类型的取值范围较大,会自动将 byte 转换为 short 类型。 在运算过程中,由于不同的数据类型会转换成同一种数据类型,所以整型、浮点型以及字符型都可以参与混合运算。自动转换的规则是从低级类型数据转换成高级类型数据。转换规则如下: ?数值型数据的转换:byte→short→int→long→float→double。 ?字符型转换为整型:char→int。 以上数据类型的转换遵循从左到右的转换顺序,最终转换成表达式中表示范围最大的变量的数据类型。 例 1 顾客到超市购物,购买牙膏 2 盒,面巾纸 4 盒。其中牙膏的价格是 10.9 元,面巾纸的价格是5.8 元,求商品总价格。实现代码如下: 1.public static void main(String[] args) { 2. float price1 = 10.9f; // 定义牙膏的价格 3. double price2 = 5.8; // 定义面巾纸的价格 4. int num1 = 2; // 定义牙膏的数量 5. int num2 = 4; // 定义面巾纸的数量 6. double res = price1 * num1 + price2 * num2; // 计算总价 7. System.out.println("一共付给收银员" + res + "元"); // 输出总价 8.} 上述代码中首先定义了一个 float 类型的变量存储牙膏的价格,然后定义了一个 double 类型的变量存储面巾纸的价格,再定义两个 int 类型的变量存储物品的数量,最后进行了乘运算以及和运算之后,将结果储存在一个 double 类型的变量中进行输出。 程序执行结果如下图 1 所示:

Java(1-4)复习题

《使用Java理解程序逻辑》1-4章阶段测试 一课后选择题 二、选择题 1、下列语句中,( BD )正确完成整形变量的声明和赋值。 A). int count,count=0; B). int count=0; C). count=0; D). int count1=0,count2=1; 2、在JAVA中,用于向控制台打印输出信息的语句是(A)。 A). System.out.println() B). System.println() C). Out.println() D). Print.println() 3、给定某Java程序的main方法如下所示,该程序的运行结果是( A)。Public static void main(String[] args){ int i=0; System.out.println(i ); } (选择一项)A A). 输出0 B). 输出1 C). 编译错误 D). 运行时出现异常 4、在Java 中,下列代码的远行结果是(D )。 public static void main(String[] args) { int a=1,b=2,c=3; if(a<0) if(b<0) c=10;

c=20; System.out.println(c); } A). 输出:10 B). 输出:20 C). 输出:3 D). 编译报错 5、在Java中,源文件Test.java中包括如下代码段,则程序编译运行结果是(b)。 public class Test{ public static void main(String[]args){ system.out.print(“Hello!”); } } A). a) 输出:Hello! B). b) 编译出错,提示“无法解析system” C). c) 运行正常,但没有输出任何内容 D). d) 运行时出现异常 6、在Java中,Scanner类提供从控制台获取键盘输入的功能,下列语句( b)能够正确实例化Scanner类的对象,用于获得键盘输入的数据。 A). Scanner input = new Scanner(System.out) B). Scanner input = new Scanner(System.in) C). Scanner input = new Scanner(System) D). Scanner input = new Scanner() 7、下面程序的执行结果是( c) public class Weather { public static void main(String[] args) { int shiDu=45; if(shiDu>=80){ System.out.println("要下雨了"); }else if(shiDu>=50){ System.out.println("天很阴"); }else if(shiDu>=30){ System.out.println("很舒适"); }else if(shiDu>=0){ System.out.println("很干燥");

JAVA中常用数据类型之间转换的方法

Java中常用数据类型之间转换的方法 Java中几种常用的数据类型之间转换方法: 1.short-->int转换 exp:short shortvar=0; int intvar=0; shortvar=(short)intvar 2.int-->short转换 exp:short shortvar=0; int intvar=0; intvar=shortvar; 3.int->String转换 exp:int intvar=1; String stringvar; Stringvar=string.valueOf(intvar); 4.float->String转换 exp:float floatvar=9.99f; String stringvar;

Stringvar=String.valueOf(floatvar); 5.double->String转换 exp double doublevar=99999999.99; String stringvar; Stringvar=String.valueOf(doublevar); 6.char->String转换 exp char charvar=’a’; String stringvar; Stringvar=String.valueOf(charvar); 7String->int、float、long、double转换Exp String intstring=”10”; String floatstring=”10.1f”; String longstring=”99999999”; String doubleString=”99999999.9”; Int I=Integer.parseInt(intstring); Float f=Integer.parseInt(floatstring); Long lo=long.parseInt(longstring); Double d=double.parseInt(doublestring); 8String->byte、short转换

实验6 泛型与集合框架_附答案

任务一:用LinkedList存放对象 1.利用面向对象的思想,创建以下类: ●Person类,包含Person的姓名和身份证号码,覆盖Object类的toString() 方法,显示“姓名:XXX 身份证号:XXX”。 ●Student类,继承Person类,包含学生的语文、数学、英文课的成绩,并覆盖 父类的toString()方法,显示“姓名:XXX 身份证号:XXX 语文:XXX 数学:XXX 英文:XXX”。 ●Teacher类,继承Person类,包含教师的工资。并覆盖父类的toString()方 法,显示“姓名:XXX 身份证号:XXX 工资:XXX”。 ●public class Person implements Comparable{ ●String name; ●String ID; ●Person(String s,String i){ ●name=s; ●ID=i; } ●public String toString() { ●String str="姓名:"+name+" 身份证号码:"+ID; ●return str; } ●public int compareTo(Object arg0) { ●Person p=(Person)arg0; ●return https://www.360docs.net/doc/b113336528.html,pareTo(p.ID); } } ●class Student extends Person { ●int Chinese; ●int Math; ●int English; ●Student(String n,String i,int c,int m,int e){ ●super(n,i); ●Chinese=c; ●Math=m; ●English=e; } ●public String toString() { ●String str; ●str=" 语文成绩:"+Chinese+" 数学成绩:"+Math+" 英语成绩: "+English; ●return super.toString()+str; ●} ●} ●class Teacher extends Person{ ●int salary; ●Teacher(String n,String i,int s){ ●super(n,i); ●salary=s; ●}

相关文档
最新文档