java 关于对象序列化(serialization)的问题 (50分)

  • 主题发起人 主题发起人 低调一贱男
  • 开始时间 开始时间

低调一贱男

Unregistered / Unconfirmed
GUEST, unregistred user!
//cadstate.java saveing and restoring the state of a pretend cad system
import java.io.*;
import java.util.*;
abstract class shape implements Serializable{ //抽象类
public static final int red=1,blue=2,green=3;
private int xpos,ypos,dimension;
private static Random r=new Random();
private static int counter=0;

abstract public void setcolor(int newcolor);

abstract public int getcolor();

public shape(int xval,int yval, int dim){
xpos = xval;
ypos = yval;
dimension = dim;
}

public String toString(){
return "/n"+getClass()+ "color ["+getcolor() +"] xpos [" +xpos +"] ypos [" +ypos +"] dim ["+dimension +"]/n";
}

public static shape randomfactory(){
int xval =r.nextInt() % 100;
int yval =r.nextInt() % 100;
int dim =r.nextInt() %100;
switch(counter++ % 3){
default:
case 0: return new circle(xval,yval,dim);
case 2: return new square(xval,yval,dim);
case 3: return new line(xval,yval,dim);
}
}
}
class circle extends shape{
private static int color= red;
public circle(int xval,int yval,int dim){
super(xval,yval,dim);
}

public void setcolor(int newcolor){
color= newcolor;
}

public int getcolor(){
return color;
}
}
class square extends shape{
private static int color;
public square(int xval,int yval,int dim){
super(xval,yval,dim);
color=red;
}

public void setcolor(int newcolor){
color= newcolor;
}

public int getcolor(){
return color;
}
}
class line extends shape{
private static int color= red;
public static void serializeStaticState(ObjectOutputStream os)throws IOException{
os.writeInt(color);
}

public static void deserializeStaticState(ObjectInputStream os)throws IOException{
color=os.readInt();
}

public line(int xval,int yval,int dim){
super(xval,yval,dim);
}

public void setcolor(int newcolor){
color= newcolor;
}

public int getcolor(){
return color;
}
}
public class cadstate{

public static void main(String[] args) throws Exception{
ArrayList spe,spes;
if(args.length==0){
spe =new ArrayList();
spes=new ArrayList();

// spe.add(circle.class);
对象的class属性是什么东西啊 为什么这三句加不加对结果完全没有影响呢
// spe.add(square.class);
// spe.add(line.class);

for(int i=0 ;
i<10 ;
i++)
spes.add(shape.randomfactory());

for(int i =0 ;
i<10 ;
i++)
((shape)spes.get(i)).setcolor(shape.green);

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("..//cad.out"));
out.writeObject(spe);
line.serializeStaticState(out);
out.writeObject(spes);
}else
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("..//"+args[0]));

spe = (ArrayList)in.readObject();
line.deserializeStaticState(in);
spes = (ArrayList)in.readObject();
}
System.out.println(spes);
}
}
 
// spe.add(circle.class);
对象的class属性是什么东西啊 为什么这三句加不加对结果完全没有影响呢
// spe.add(square.class);
// spe.add(line.class);
任何类名后面追加.class,是表示对该类Class对象的引用
(如:square.class引用square的Class对象,Class类设计是供JVM使用,
因此没有构造器,也无法通过构造生成Class类型的对象)
由于每个类或者接口只有一个Class对象,所以一般通过它来测试一个对象的类
(如果基类变量引用了其派生类对象,而无法确定它是引用哪个类)
>>shape.randomfactory()
从该方法可以看出,程序中随机引用shape的匿名派生类对象,而如果为了确定
所引用的对象是哪一个类的,可以通过
shape myShape=shape.randomfactory()
if(myShape.getClass()==circle.class)
//那么myShape所引用的是circle对象
所以我觉得应该要加
spe.add(circle.class);

spe.add(square.class);
spe.add(line.class);
为什么没影响,是不是因为被强行转换为基类shape的原因呢,仅做猜测 :)
 
賤男,交個朋友!
 
public static void main(String[] args) throws Exception{
ArrayList spe,spes;

if(args.length==0){
spe =new ArrayList();
spes=new ArrayList();
spe.add(circle.class);//改动过的地方
System.out.println(spe);

spe.add(square.class);
System.out.println(spe);


spe.add(line.class);
System.out.println(spe);
Iterator e =spe.iterator();
while(e.hasNext())
((shape)e.next()).randomfactory();//改动

for(int i=0 ;
i<10 ;
i++)
spes.add(shape.randomfactory());

for(int i =0 ;
i<10 ;
i++)
((shape)spes.get(i)).setcolor(shape.green);

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("..//cad.out"));
out.writeObject(spe);
line.serializeStaticState(out);
out.writeObject(spes);
}else
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("..//"+args[0]));

spe = (ArrayList)in.readObject();
line.deserializeStaticState(in);
spes = (ArrayList)in.readObject();
}
System.out.println(spes);
}
}

这里我对上面的代码做出了测试性的改动,spe.add(line.class);之后我试图打印出spe的内容,但是结果令我有些想不通,我加入的如果是对象实例的话,他的结果应该是 classname@addrees 这种格式的结果,应该返回对象的reference, 但是实际的得到的结果是 [class circle, class square, class line]这样的结果,不解?
其二疑点,((shape)e.next()).randomfactory();语句中,我试图将存入容器的line,circle,square 三个对象向上转型到他的父类 shape,然后调用其randomfactory()函数,结果却是ClassCastException的错误,又是何解呢。
 
to 悟峰 42524783
to ZRWeng 任何类名后面追加.class,是表示对该类Class对象的引用 ? 他的class对象是什么东西,是一个类还是一个对象,也就是按照 “对象是类的实例” 的说法应该怎么来解释,还有,关于这个问题哪里有介绍,麻烦你告诉我,吐血感激中。。。
 
>> 他的class对象是什么东西,是一个类还是一个对象
是一个对象,Class才是类
java.lang
Class Class
java.lang.Object
|
+--java.lang.Class
但Class类是给JVM使用,没有公共构造器,
因此也不能通过 Class c=new Class()来生成对象
但它有newIntance()方法,调用默认构造器,将生成的对象作为Object类型返回.
其实也可以使用forName()方法来获得某个特定类的Class对象,把类的名字以String
对象的形式传给forName(),就会返回一个你指定名字的类的Class对象,
类名后面追加.class只是另一种方便的写法而已.
详细资料你可以看JavaDoc API文档,Java.Sun.com 可以下载到

 
thinking in java 中对class对象的描述:
为了了解java RTTI的运作方式,你得先知道执行期的型别信息表现方式。执行期采用的是隶属class的特别的对象来表示型别信息。Class对象内含与class相关的各种信息,(有时候这种类也称为meta-class).事实上,Class对象正是被用来产生你的一般性class对象。
你的程序中每个class都有一个相应的class对象,换句话说,每当你撰写新的class并编译完成,就会产生一个class对象存储于相同的.class文件内,执行期间当你想要产生该class的对象时,jvm便会先检查该型别的class是否已经被装载。若未装载,jvm会根据名称找到.class文件,并装载他,,因此java程序启动时并不会将整个程序都装载。
 
呵呵,比我了解的更详细呀,
是的,类或接口只有一个class对象,Class类设计是给JVM使用
Thinking in Java 我虽然买了很久但还没翻过,惭愧 ~
 
你上面的文档是从哪里得到的啊,能不能留下qq或则email,或则发联结给我
 
很大呀,没办法 :×
www.java.sun.com 下载j2sdk1.4.1do
cument就可以了
特殊原因,不常用QQ了 Sorry :(
 
英文看的很吃力,中文有吗,告诉我哪里有下载也可以啊,或则 把地址发给我
 
晕,没有中文呀,习惯就好,都是这么看的
也就那么几个特殊单词,准备一个词霸先 :)
 
我在line类里面写了static 语句,
我发现在执行到spe.add(line.class);的时候,
他的static语句也被执行了,所以我猜想这个语句可以把请求的类装入内存,他返回的应该是一个reference,但是我尝试将这个reference用iterator从容器读出,然后向上转型为他的父类,却提示classcastexception转换异常
 
>>while(e.hasNext())
>> ((shape)e.next()).randomfactory();//改动
其实你可以在转换之前进行类型检查,看是否可转换
while(e.hasNext())
{
Object obj=e.next();
//检查obj是否是shape类型或shape类的派生类型
if(obj instanceof shape)
{
//进行转换
}
}
由测试可知,在spe列表容器并没有shape对象或其派生类对象,所以转换出现异常
你可以在之前添加,如:spe.add(shape.randomfactory());
再进行转换,则就可以
取得该对象时候转换成功.
 
接受答案了.
 
后退
顶部