??xml version="1.0" encoding="utf-8" standalone="yes"?>
import java.io.*; import java.util.Date; /** * 对象的序列化和反序列化测试类. * @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a> * @version 1.0 * Creation date: 2007-9-15 - 下午21:45:48 */ public class ObjectSaver { /** * @param args * @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a> * Creation date: 2007-9-15 - 下午21:45:37 */ public static void main(String[] args) throws Exception { ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream("D:""objectFile.obj")); //序列化对?br /> Customer customer = new Customer("阿蜜?, 24); out.writeObject("你好!"); out.writeObject(new Date()); out.writeObject(customer); out.writeInt(123); //写入基本cd数据 out.close(); //反序列化对象 ObjectInputStream in = new ObjectInputStream (new FileInputStream("D:""objectFile.obj")); System.out.println("obj1=" + (String) in.readObject()); System.out.println("obj2=" + (Date) in.readObject()); Customer obj3 = (Customer) in.readObject(); System.out.println("obj3=" + obj3); int obj4 = in.readInt(); System.out.println("obj4=" + obj4); in.close(); } } class Customer implements Serializable { private String name; private int age; public Customer(String name, int age) { this.name = name; this.age = age; } public String toString() { return "name=" + name + ", age=" + age; } } |
obj1=你好! obj2=Sat Sep 15 22:02:21 CST 2007 obj3=name=阿蜜? age=24 obj4=123 |
private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; |
public void writeExternal(ObjectOutput out) throws IOException public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException |
private static final long serialVersionUID; |
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.CollationKey;
import java.text.Collator;
import java.text.RuleBasedCollator;
import java.util.*;
/**
* <strong>Title : ListComparator </strong>. <br>
* <strong>Description : List排序器(支持中文排序Q?</strong> <br>
*/
public class ListComparator implements Comparator {
/**
* <code>collator</code> - 排序规则控制?
*/
private RuleBasedCollator collator = (RuleBasedCollator) Collator
.getInstance(java.util.Locale.CHINA);
/**
* <code>methodName</code> - 排序字段的方法名.
*/
private String methodName;
/**
* <code>seq</code> - 排序序.
*/
private String seq;
/**
* <code>methodeArgs</code> - Ҏ参数.
*/
private Object[] methodeArgs;
/**
* 构造函?List中存攑֤杂对象,q且获得排序字段值的Ҏ需要参?.
*
* @param methodName
* -对象中的Ҏ?br /> * @param methodeArgs
* -Ҏ参数
* @param seq
* -排序序
* @throws Exception
*/
public ListComparator(String methodName, Object[] methodeArgs, String seq)
throws Exception {
this.methodName = methodName;
this.methodeArgs = methodeArgs;
if (!"asc".equalsIgnoreCase(seq) && !"desc".equalsIgnoreCase(seq)) {
throw new Exception("illegal value of parameter 'seq' for input '"
+ seq + "'");
}
this.seq = seq;
}
/**
* 构造函?List中存攑֤杂对象,q且获得排序字段值的Ҏ不需要参?.
*
* @param methodName
* @param seq
* @throws Exception
*/
public ListComparator(String methodName, String seq) throws Exception {
this.methodName = methodName;
if (!"asc".equalsIgnoreCase(seq) && !"desc".equalsIgnoreCase(seq)) {
throw new Exception("illegal value of parameter 'seq' for input '"
+ seq + "'");
}
this.seq = seq;
}
/**
* 构造函?List中存攄单对?.
*
* @param seq
* @throws Exception
*/
public ListComparator(String seq) throws Exception {
if (!"asc".equalsIgnoreCase(seq) && !"desc".equalsIgnoreCase(seq)) {
throw new Exception("illegal value of parameter 'seq' for input '"
+ seq + "'");
}
this.seq = seq;
}
/**
* (non-Javadoc).
*
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object obj1, Object obj2) {
int t_ret = 0;
// 如果指定了方法名Q则表示List中存攄是复杂对?br /> if (this.methodName != null && !"".equals(this.methodName)) {
// 执行Bean中的ҎQ得到方法返回的对象
Object t_obj1 = invokeMethod(obj1, this.methodName,
this.methodeArgs);
Object t_obj2 = invokeMethod(obj2, this.methodName,
this.methodeArgs);
t_ret = selectCompare(t_obj1, t_obj2);
} else {
t_ret = selectCompare(obj1, obj2);
}
return t_ret;
}
/**
* 执行对象的某个方?
*
* @param owner
* -对象
* @param methodName
* -Ҏ?br /> * @param methodArgs
* -Ҏ参数
*
* @return Ҏq回对象
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws Exception
*/
private Object invokeMethod(Object owner, String methodName,
Object[] methodArgs) {
Class[] argsClass = null;
if (methodArgs != null && methodArgs.length > 0) {
argsClass = new Class[methodeArgs.length];
for (int i = 0, j = methodeArgs.length; i < j; i++) {
argsClass[i] = methodeArgs[i].getClass();
}
}
Class ownerClass = owner.getClass();
Method method;
Object t_object = null;
try {
method = ownerClass.getMethod(methodName, argsClass);
t_object = method.invoke(owner, methodArgs);
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
argsClass = new Class[1];
argsClass[0] = Object.class;
try {
method = ownerClass.getMethod(methodName, argsClass);
t_object = method.invoke(owner, methodArgs);
} catch (SecurityException e1) {
} catch (NoSuchMethodException e1) {
} catch (IllegalArgumentException e1) {
} catch (IllegalAccessException e1) {
} catch (InvocationTargetException e1) {
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return t_object;
}
private int selectCompare(Object obj1, Object obj2) {
int t_ret = 0;
if (obj1 instanceof String && obj2 instanceof String) {
t_ret = compareString(obj1, obj2);
}
if (obj1 instanceof Integer && obj2 instanceof Integer) {
t_ret = compareInt(obj1, obj2);
}
if (obj1 instanceof Long && obj2 instanceof Long) {
t_ret = compareLong(obj1, obj2);
}
if (obj1 instanceof Date && obj2 instanceof Date) {
t_ret = compareDate(obj1, obj2);
}
return t_ret;
}
private int compareString(Object obj1, Object obj2) {
int ret = 0;
String s1 = (String) obj1;
String s2 = (String) obj2;
CollationKey c1 = collator.getCollationKey(s1);
CollationKey c2 = collator.getCollationKey(s2);
ret = collator.compare(c1.getSourceString(), c2.getSourceString());
if (seq.equalsIgnoreCase("desc")) {
ret = ret * -1;
}
return ret;
}
private int compareInt(Object obj1, Object obj2) {
int ret = 0;
int i1 = ((Integer) obj1).intValue();
int i2 = ((Integer) obj2).intValue();
if (i1 < i2)
ret = -1;
else if (i1 > i2)
ret = 1;
else
ret = 0;
if (seq.equalsIgnoreCase("desc")) {
ret = ret * -1;
}
return ret;
}
private int compareLong(Object obj1, Object obj2) {
int ret = 0;
long l1 = ((Long) obj1).longValue();
long l2 = ((Long) obj2).longValue();
if (l1 < l2)
ret = -1;
else if (l1 > l2)
ret = 1;
else
ret = 0;
if (seq.equalsIgnoreCase("desc")) {
ret = ret * -1;
}
return ret;
}
private int compareDate(Object obj1, Object obj2) {
int ret = 0;
Date d1 = (Date) obj1;
Date d2 = (Date) obj2;
ret = d1.compareTo(d2);
if (seq.equalsIgnoreCase("desc")) {
ret = ret * -1;
}
return ret;
}
}
-------------------------------------------------------------------
使用
-------------------------------------------------------------------
private List getSortedList(List unsortedList, String methodName,
Object methodArgs[], String orderSequence) throws Exception {
ListComparator t_compare = null;
if (null != methodName && !"".equals(methodName)) {
if (methodArgs != null && methodArgs.length > 0)
t_compare = new ListComparator(methodName, methodArgs,
orderSequence);
else
t_compare = new ListComparator(methodName, orderSequence);
} else {
t_compare = new ListComparator(orderSequence);
}
List t_list = unsortedList;
Collections.sort(t_list, t_compare);
return t_list;
}
abstract class和interface是语a中对于抽象类定义q行支持的两U机Ӟ正是׃q两U机制的存在Q才赋予了Java强大的面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的怼性,甚至可以怺替换Q因此很多开发者在q行抽象cd义时对于abstract class和interface的选择昑־比较随意。其实,两者之间还是有很大的区别的Q对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意囄理解是否正确、合理。本文将对它们之间的区别q行一番剖析,试图l开发者提供一个在二者之间进行选择的依据。 ?/font> 理解抽象c ?/font> abstract class和interface在Java语言中都是用来进行抽象类Q本文中的抽象类q从abstract class译而来Q它表示的是一个抽象体Q而abstract class为Java语言中用于定义抽象类的一U方法,误者注意区分)定义的,那么什么是抽象c,使用抽象c能为我们带来什么好处呢Q ?/font> 在面向对象的概念中,我们知道所有的对象都是通过cL描绘的,但是反过来却不是q样。ƈ不是所有的c都是用来描l对象的Q如果一个类中没有包含够的信息来描l一个具体的对象Q这Lcd是抽象类。抽象类往往用来表征我们在对问题领域q行分析、设计中得出的抽象概念,是对一pd看上M同,但是本质上相同的具体概念的抽象。比如:如果我们q行一个图形编辑Y件的开发,׃发现问题领域存在着圆、三角Şq样一些具体概念,它们是不同的Q但是它们又都属于Ş状这样一个概念,形状q个概念在问题领域是不存在的Q它是一个抽象概c正是因为抽象的概念在问题领域没有对应的具体概念Q所以用以表征抽象概늚抽象cL不能够实例化的。 ?/font> 在面向对象领域,抽象cM要用来进行类型隐藏。我们可以构造出一个固定的一l行为的抽象描述Q但是这l行为却能够有Q意个可能的具体实现方式。这个抽象描q就是抽象类Q而这一lQ意个可能的具体实现则表现为所有可能的zcR模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允怿改的Q同Ӟ通过从这个抽象体zQ也可扩展此模块的行为功能。熟悉OCP的读者一定知道,Z能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle)Q抽象类是其中的关键所在。 ?/font> 从语法定义层面看abstract class和interface 在语法层面,Java语言对于abstract class和interfacel出了不同的定义方式Q下面以定义一个名为Demo的抽象类Z来说明这U不同。 ?/font> 使用abstract class的方式定义Demo抽象cȝ方式如下Q ?/font> abstract class Demo { ?/font> abstract void method1(); abstract void method2(); … ?/font> } ?/font> 使用interface的方式定义Demo抽象cȝ方式如下Q ?/font> interface Demo { void method1(); void method2(); … ?/font> } 在abstract class方式中,Demo可以有自q数据成员Q也可以有非abstarct的成员方法,而在interface方式的实CQDemo只能够有静态的不能被修改的数据成员Q也是必须是static final的,不过在interface中一般不定义数据成员Q,所有的成员Ҏ都是abstract的。从某种意义上说Qinterface是一U特DŞ式的abstract class。 ?/font> 从编E的角度来看Qabstract class和interface都可以用来实?design by contract"的。但是在具体的用上面还是有一些区别的。 ?/font> 首先Qabstract class在Java语言中表C的是一U承关p,一个类只能使用一ơ承关pR但是,一个类却可以实现多个interface。也许,q是Java语言的设计者在考虑Java对于多重l承的支持方面的一U折中考虑吧。 ?/font> 其次Q在abstract class的定义中Q我们可以赋予方法的默认行ؓ。但是在interface的定义中Q方法却不能拥有默认行ؓQؓ了绕q这个限Ӟ必须使用委托Q但是这会 增加一些复杂性,有时会造成很大的麻烦。 ?/font> 在抽象类中不能定义默认行存在另一个比较严重的问题Q那是可能会造成l护上的ȝ。因为如果后来想修改cȝ界面Q一般通过abstract class或者interface来表C)以适应新的情况Q比如,d新的Ҏ或者给已用的方法中d新的参数Q时Q就会非常的ȝQ可能要p很多的时_对于zcd多的情况Q尤为如此)。但是如果界面是通过abstract class来实现的Q那么可能就只需要修改定义在abstract class中的默认行ؓ可以了。 ?/font> 同样Q如果不能在抽象cM定义默认行ؓQ就会导致同LҎ实现出现在该抽象cȝ每一个派生类中,q反?one ruleQone place"原则Q造成代码重复Q同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心?/font> |
Java 5.0发布了,许多人都开始用这个JDK版本的一些新增特性。从增强的for循环到诸如泛?generic)之类更复杂的Ҏ,都将很快出现在您所~写的代码中。我们刚刚完成了一个基于Java 5.0的大型Q务,而本文就是要介绍我们使用q些新特性的体验。本文不是一入门性的文章Q而是对这些特性以及它们所产生的媄响的深入介绍Q同时还l出了一些在目中更有效C用这些特性的技巧?
?/strong>
增强的for循环
Init表达?/strong>
局限?/strong>
我们希望数l中的值打Cؓ一个用逗号分隔的清单。我们需要知道目前是否是W一,以便定是否应该打印逗号。用增强的for循环是无法获知这U信息的。我们需要自׃留一个下标或一个布值来指示是否l过了第一V? q是另一个例子: 在此例中Q我们想从整数集合中删除负数Vؓ此,需要对q代器调用一个方法,但是当用增强的for 循环Ӟq代器对我们来说是看不到的。因此,我们只能使用Java 5之前版本的P代方法? Z说一下,q里需要注意的是,׃Iterator是泛型,所以其声明是Iterator
注释
Suppress Warnings
q可能是内置注释最有用的地斏V遗憄是,1.5.0_04的javac不支持它。但?.6支持它,q且Sun正在努力其向后UL?.5中?
Deprecated
Override
看上面的例子Q如果没有在hashCode中将“C”大写Q在~译时不会出现错误,但是在运行时无法像期望的那栯用该Ҏ。通过dOverride标签Q编译器会提C它是否真正地执行了重写?
其它注释 其思想是ؓU有字段bar自动创徏getter和setterҎ。遗憄是,q个x有两个失败之处:1)它不能运行,2)它代码难以阅读和处理? 它是无法实现的,因ؓ前面已经提到了,Sun特别L了对出现注释的类q行修改?
枚D
现在枚Dcd可以直接提供它的实用Ҏ。例如:
当讨论可变参数时Q比较有的是,如果用新的可变参数替换前四个例子Q将是兼容的Q? Ҏ{应该如下所C,相应的可变参数分别用String和Exception声明Q? 协变q回的用替换了三个反模式: ZooImpl._animal ((AnimalImpl)ZooImpl.getAnimal()).implMethod(); ZooImpl._getAnimal();
泛型Ҏ 在示例用法中Q我们传入了一个int。所以方法的q回cd是List
不带参数的泛型方?br /> emptyList()Ҏ与泛型一起引入,作ؓjava.util.Collections中EMPTY_LIST字段的类型安全置换: 与先前的例子不同Q这个方法没有参敎ͼ那么~译器如何推断T的类型呢Q基本上Q它尝试用一ơ参数。如果没有v作用Q它再次试使用q回或赋值类型。在本例中,q回的是List 因ؓ~译器看不到q回上下文,也不能推断TQ所以它攑ּq用Object。您看C个错误消息,比如Q?#8220;无法List< Object >转换为List q种情况l常发生的另一个地Ҏ在方法调用中。如果一个方法带一个List
集合之外
通配W?br /> 泛型最复杂的部分是寚w配W的理解。我们将讨论三种cd的通配W以及它们的用途? 如果使用泛型Q只要代码在~译时没有出现警告,׃会遇到运行时ClassCastException?
上限通配W?/strong>
上限 我们可以从列表中得到NumberQ因为无论列表的切元素cd是什么(Float、Integer或NumberQ,我们都可以把它赋值给Number?
Z么用通配W?br /> 在下面这个例子中Q通配W用于向API的用户隐藏类型信息。在内部QSet被存储ؓCustomerImpl。而API的用户只知道他们正在获取一个SetQ从中可以读取Customer?
通配W和协变q回
如果要用数l,接口可以q回Number[]Q而实现可以返回Integer[]?
下限
下限与上?br />
W一个是可以从中L的列表?
无界通配W?/strong>
公共API中的通配W?
构造泛型类?/strong>
集合风格(Collection-like)的函?/strong>
q从方法返回两个项而无需为每个两U类型的l合~写专用的类成ؓ可能。另一U方法是q回Object[]Q而这hcd不安全或者不整洁的?
集合之外
泛型Ҏ
具体?br /> 当实C个泛型类Ӟ您可能想要构造一个数lT[]。因为泛型是通过擦除(erasure)实现的,所以这是不允许的?
具体化解x?br /> 按照泛型教程的惯例,解决Ҏ使用的是“cd令牌”Q通过向构造函数添加一个Class Z构造ArrayExample
l束?/strong>
补充阅读
原文出处:Experiences with the New Java 5 Language Features http://dev2dev.bea.com/pub/a/2005/09/java_5_features.html <!--文章其他信息-->
|
c集包含一个add(Object obj)ҎQ因此可以包含Q意Object数据Q但是不能直接存储:intQchar,Double{数据。可以用下面的Ҏ实现Q?br />ArrayList a=new ArrayList();
a.add(new Integer(1));
a.add(new Integer(2));
…?/p>
当类集不能被修改Ӟ可能引发 UnsupportedOperationException异常。企囑ְ一个不兼容的对象加入到一个类集中时可能引发ClassCastException异常?/p>
List接口Q从Collectionl承而来Q用基?的下标)
void add(int index,Object obj) 插入点以后的元素后U?br />boolean addAll(int index,Collection c) 如果调用列表改变了,q回true,否则q回false
Object get(int index)
int indexOf(Object obj) q回obj对象在列表中的烦引,不存在返?1
int lastIndexOf(Object obj) q回obj在列表中的最后一个实例的下标Q不存在q回-1
ListIterator listIterator()
ListIterator listIterator(int index) q回index开始的q代E序
Object set(int index,Object obj) 对列表index处的D行修?br />List subList(int start,int end) 从start到end-1
Set接口Q从CollectionzQ没有定义新的方法)
Set不允许有重复的元素?br />对Set调用addQObject objQ方法,如果obj已经存在集合中,返回false?/p>
SortedSet接口
Comparator comparator() q回调用排序集合的比较函敎ͼ如果攚w合用自焉序,则返回null
Object first() q回被排序集合的W一个元?br />SortedSet headSet(Object end) q回一个包含小于end元素的SortedSet
Object last() q回调用排序集合的最后一个元?br />SortedSet subSet(Object start,Object end) 包括从start到end-1
SortedSet tailSet(Object start) q回包含大于{于start的元?br />
ArrayList扩展AstractListc,q执行List接口。ArrayList支持动态长度的数组?br />LinkList扩展了AbstractSequentialListQ执行List接口。提供连接列表?br />HashSet扩展AbstractSet实现Set接口Q元素没有顺序。对于大集合提供帔RU基本操作?br />TreeSet使用树来存储的SetQ对象按升序存储。访问和索非常快?/p>
iterator实现Iterator接口或者ListIterator接口?br />Iterator接口
boolean hasNext()
Object next() 如果没有下一个元素则引发NoSuchElementException异常?br />void remove() 删除当前元素Q如果试囑֜调用next()Ҏ后调用remove()Ҏ则引发IllegalStateException异常?br />
ListIterator接口
void add(Object obj) 一个元素插入到当前元素之前Q调用next()Ҏ返回该元素?br />boolean hasNext()
boolean hasPrevious()
Object next() 如果不存在引发NoSuchElementException
int nextIndex() 如果不存在返回列表的大小
void remove()
void set(Object obj) 修改当前元素
public void test1() {
ArrayList al = new ArrayList();
for (int i = 1; i < 10; i++) {
al.add("ArrayList Element:" + i);
}
Iterator itr = al.listIterator();
while (itr.hasNext()) {
Object obj = itr.next();
System.out.println(obj);
}
}
public void test2() {
HashSet hs = new HashSet();
System.out.println("HashSet");
for (int i = 1; i < 10; i++) {
hs.add("HashSet Element:" + i);
}
Iterator itr = hs.iterator();
while (itr.hasNext()) {
Object obj = itr.next();
System.out.println(obj);
}
}
public void test3() {
TreeSet ts = new TreeSet();
System.out.println("TreeSet");
for (int i = 1; i < 10; i++) {
ts.add("TreeSet Element:" + i);
}
Iterator itr = ts.iterator();
while (itr.hasNext()) {
Object obj = itr.next();
System.out.println(obj);
}
}
public void test4()
{
HashMap hm=new HashMap();
for ( int i=0;i<10;i++)
{
hm.put("item"+i,"value"+i);
}
Set set=hm.entrySet();
Iterator itr=set.iterator();
while (itr.hasNext())
{
Map.Entry me=(Map.Entry)itr.next();
System.out.println(me.getKey()+";"+me.getValue());
}
hm.put("item5","modifyed value");
System.out.println(hm.get("item5") );
set=hm.entrySet();
itr=set.iterator();
while (itr.hasNext())
{
Map.Entry me=(Map.Entry)itr.next();
System.out.println(me.getKey()+";"+me.getValue());
}
}
如果现在要求Doorq要h报警的功能。我们该如何设计针对该例子的cȝ构呢Q在本例中,主要是ؓ了展Cabstract class和interface反映在设计理念上的区别,其他斚w无关的问题都做了化或者忽略)Q下面将|列出可能的解决ҎQƈ从设计理念层面对q些不同的方案进行分析?
解决Ҏ一Q?
单的在Door的定义中增加一个alarmҎQ如下:
abstract class Door{
abstract void open();
abstract void close()Q?
abstract void alarm();
}
或?
interface Door{
void open();
void close();
void alarm();
}
那么h报警功能的AlarmDoor的定义方式如下:
class AlarmDoor extends Door{
void open(){…}
void close(){…}
void alarm(){…}
}
或?
class AlarmDoor implements Door?
void open(){…}
void close(){…}
void alarm(){…}
?
q种Ҏq反了面向对象设计中的一个核心原则ISPQInterfaceSegregationPricipleQ,在Door的定义中把Door概念本n固有的行为方法和另外一个概?报警?的行为方法在了一赗这样引L一个问题是那些仅仅依赖于Doorq个概念的模块会因ؓ"报警?q个概念的改变(比如Q修改alarmҎ的参敎ͼ而改变,反之依然?
解决Ҏ二:
既然open、close和alarm属于两个不同的概念,ҎISP原则应该把它们分别定义在代表q两个概늚抽象cM。定义方式有Q这两个概念都用abstract class方式定义Q两个概念都使用interface方式定义Q一个概念用abstract class方式定义Q另一个概念用interface方式定义?
昄Q由于Java语言不支持多重承,所以两个概念都使用abstract class方式定义是不可行的。后面两U方式都是可行的Q但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意囄反映是否正确、合理。我们一一来分析、说明?
如果两个概念都用interface方式来定义,那么反映出两个问题Q?、我们可能没有理解清楚问题领域,AlarmDoor在概忉|质上到底是Doorq是报警器?2、如果我们对于问题领域的理解没有问题Q比如:我们通过对于问题领域的分析发现AlarmDoor在概忉|质上和Door是一致的Q那么我们在实现时就没有能够正确的揭C我们的设计意图Q因为在q两个概늚定义上(均用interface方式定义Q反映不Zq含义?
如果我们对于问题领域的理解是QAlarmDoor在概忉|质上是DoorQ同时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢Q前面已l说q,abstract class在Java语言中表CZU承关p,而承关pd本质上是"isa"关系。所以对于Doorq个概念Q我们应该用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行ؓQ所以报警概念可以通过interface方式定义。如下所C:
abstract class Door{
abstract void open();
abstract void close()Q?
}
interface Alarm{
void alarm();
}
class AlarmDoor extends Door implements Alarm{
void open(){…}
void close(){…}
void alarm(){…}
}
q种实现方式基本上能够明的反映出我们对于问题领域的理解Q正的揭示我们的设计意图。其实abstract class表示的是"isa"关系Qinterface表示的是"likea"关系Q大家在选择时可以作Z个依据,当然q是建立在对问题领域的理解上的,比如Q如果我们认为AlarmDoor在概忉|质上是报警器Q同时又hDoor的功能,那么上述的定义方式就要反q来了?/p>
一行一行读取数?br /><%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>文gd</title>
</head>
<body>
<%
String path=request.getRealPath("");//取得当前目录的\?br /> FileReader fr=new FileReader(path + "file://file//inc//t.txt%22);//建立FileReader对象Qƈ实例化ؓfr
BufferedReader br=new BufferedReader(fr);//建立BufferedReader对象Qƈ实例化ؓbr
String Line=br.readLine();//从文件读取一行字W串
//判断d到的字符串是否不为空
while(Line!=null){
out.println(Line + "<br>");//输出从文件中d的数?br /> Line=br.readLine();//从文件中l箋d一行数?br /> }
br.close();//关闭BufferedReader对象
fr.close();//关闭文g
%>
</body>
</html>
略过文g中的字符不读?br /><%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>略过字节不读?lt;/title>
</head>
<body>
<%
String path=request.getRealPath(".");
FileReader fr=new FileReader(path + "file://ReadData.txt/");
fr.skip(2);//跌2个字?br />int c=fr.read();//d一个字?br />while(c!=-1){
out.print((char)c);
c=fr.read();
}
fr.close();
%>
</body>
</html>
数据写入文?br /><%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>数据写入文?lt;/title>
</head>
<body>
<%
String path=request.getRealPath(".");
FileWriter fw=new FileWriter(path + "file://WriteData.txt%22);//建立FileWriter对象Qƈ实例化fw
//字W串写入文g
fw.write("大家好!");
fw.write("本书是《JSP~程技巧?);
fw.write("请多多指教!");
fw.write("email:stride@sina.com");
fw.close();
FileReader fr=new FileReader(path + "file://WriteData.txt/");
BufferedReader br=new BufferedReader(fr);//建立BufferedReader对象Qƈ实例化ؓbr
String Line=br.readLine();
//d一行数?br />out.println(Line + "<br>");
br.close();//关闭BufferedReader对象
fr.close();
%>
</body>
</html>
写入文件的数据分行
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>写入文件的数据分行</title>
</head>
<body>
<%
String path=request.getRealPath(".");
FileWriter fw=new FileWriter(path + "file://WriteData.txt/");
BufferedWriter bw=new BufferedWriter(fw);
bw.write("大家好!");
bw.write("本书是《JSP~程技巧》?);
bw.newLine();//断行
bw.write("请多多指教!");
bw.newLine();//断行
bw.write("email: stride@sina.com");
bw.flush();//数据更新至文g
fw.close();//关闭文g?br />out.println("写入文g内容为:<br>");
FileReader fr=new FileReader(path + "file://WriteData.txt/");
BufferedReader br=new BufferedReader(fr);
String Line=br.readLine();//d一行数?br />while(Line!=null){
out.println(Line + "<br>");
Line=br.readLine();
}
fr.close();
%>
</body>
</html>
如何数据追加写入到文g
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>写入文件的数据分行</title>
</head>
<body>
<%
String path=request.getRealPath(".");
RandomAccessFile rf=new RandomAccessFile(path + "file://WriteData.txt%22,%22rw%22);//定义一个类RandomAccessFile的对象,q实例化
rf.seek(rf.length());//指针移动到文g末尾
rf.writeBytes("\nAppend a line to the file!");
rf.close();//关闭文g?br />out.println("写入文g内容为:<br>");
FileReader fr=new FileReader(path + "file://WriteData.txt/");
BufferedReader br=new BufferedReader(fr);//d文g的BufferedRead对象
String Line=br.readLine();
while(Line!=null){
out.println(Line + "<br>");
Line=br.readLine();
}
fr.close();//关闭文g
%>
</body>
</html>
import java.util.*;
import java.io.*;
public class ReadIni
{
public static void main(String[] args)
throws Exception
{
Properties proDB = new Properties();
FileInputStream in = new FileInputStream("DBConfig.ini");
proDB.load(in);
String jdbc = proDB.getProperty("jdbc");
String dburl = proDB.getProperty("dburl");
String userid = proDB.getProperty("userid");
String password = proDB.getProperty("password");
System.out.println(jdbc);
System.out.println(dburl);
System.out.println(userid);
System.out.println(password);
}
}
DBConfig.ini:
dburl=jdbcracle:thin:@202.16.147.104:1521ub
userid=user
password=password
jdbc=oracle.jdbc.driver.OracleDriver