Flex Module中 类型转换错误

转摘的地址:http://ljhzzyx.blog.163.com/blog/static/38380312201175230919/

背景是这样,在Flex Module中使用了远程对象,并有使用实体类,获取实体类后有类型的转换;flex sdk版本是3.2。如:

[RemoteClass(alias="serviceLibrary.systemFramework.UserInfoSearchCondition")]
public class UserInfoSearchCondition

......

      第一次切换到module时是没有问题的,但第二次切换到module,在页面获取实体类进行类型转换时,报错误:

......serviceLibrary.systemFramework::UserInfoSearchCondition@XXXX无法转换为serviceLibrary.systemFramework.UserInfoSearchCondition......


      解决方法可以使用registerClassAlias(),代码如下:
import serviceLibrary.systemFramework.UserInfoSearchCondition;
registerClassAlias("serviceLibrary.systemFramework.UserInfoSearchCondition", UserInfoSearchCondition);
      这个问题在flex sdk 3.2开始出现,3.1中没有。我本机两个项目使用flex sdk 3.5,其中一个项目存在这个问题,而相同代码在另一个项目中不会有这个问题。很是奇怪。
      以上声明放在Module中即可,如果多个Module存在这样的问题,也可以放在Application里共享。
      Flex sdk 3.2 reference 文档中说明如下:
flash.net
registerClassAlias () 函数  

public function registerClassAlias(aliasName:String, classObject:Class):void

语言版本:  ActionScript 3.0
运行时版本:  AIR 1.0 Flash Player 9

当以 Action Message Format (AMF) 对一个对象进行编码时,保留该对象的类(类型)。将对象编码为 AMF 时,该函数将保存该对象的类的别名,以便在解码对象时可以恢复该类。如果编码上下文没有为对象的类注册别名,该对象将被编码为一个匿名对象。同样,如果解码上下文注册了不同的别名,将为解码后的数据创建一个匿名对象。

LocalConnection、ByteArray、SharedObject、NetConnection 及 NetStream 均为将对象编码为 AMF 的类的示例。

编码和解码上下文不必对别名使用相同的类。它们可以主动地改变类,条件是目标类包含源类序列化的所有成员。

参数  aliasName:String — 要使用的别名。
         classObject:Class — 与给定别名相关联的类。

引发 TypeError — 如果任一个参数为 null。 

      具体原因在这里有精彩描述:
http://www.myflexhero.com/share/flex-hero-flex4/flex-hero-coding-techniques/308
      如果你在使用多个Module开发,然后远程服务器返回了同一个Object,比如User对象,可能会报这样的错误:
 TypeError: Error #1034: 强制转换类型失败:无法将 User@7412zf312 转换为User 的问题。
即使你明明知道远程返回的对象就是User对象,但是不管如何,强制转换就是报错。(很霸道!)
              这里先引用一段英文:
  If moduleA brings in MyDataClass and registers it with the alias table, it has registered MyDataClass@moduleA, and when module brings in its MyDataClass and registers it, it replaces the alias with MyDataClass@moduleB and when moduleA’s result returns, the player converts it to MyDataClass@moduleB and the types don’t match.

Hopefully, the only thing in your RSL or main app or sharedcode module is the data class and maybe a few other classes that get shared.  That might eliminate the behavior differences you’re seeing.

             ok,3点解决方法。

    1. 在Module中通过使用
    registerClassAlias("com.myflexhero.domain", User);

    再次注册实体对象的Alias为当前Module,这就意味着你每次调用完远程服务器,如果返回的是User对象,你就需要调用一次改方法,建议你将所有的对象都写在一个类的静态方法里。

    2. 为你as端的实体对象使用
    [RemoteClass]
    注解,而不是
    [RemoteClass(alias="com.myflexhero.domain.User")]

    注解。这样也就意味着每次你返回User对象,你都必须想办法手动将ObjectProxy对象转换为User对象,虽然你知道它其实就是User对象。

    3. 如英文所说,将这些实体对象放置于共享模块中。

      原因就是Module中的对象,还会加上module名的后缀。

      另外摘录registerClassAlias的用法:
registerClassAlias在利用AMF3进行序列话网络通讯中,是非常有用的。需要把客户端的对象直接传送到服务器得时候,保留该对象的类(类型)。 这样的话,就可以传送自定义对象或者系统自带对象。

readObject方法对构造器有参数的类,是会出错的,会弹出参数数量不匹配这个错误。因为还原对象进行反射的时候,是默认没有参数的给构造器的。这也是有些人 讨论Sprite等对象不能进行深度拷贝的原因,所以在使用AMF3进行序列话的时候要注意这个了,还有一个就是,如果那个类包含了多个类,也就是个复合类,那么里面的那个复合类,也必须进行registerClassAlias,例如
package
{
    import flash.geom.Point;
    
    public class Test
    {
        public var name:String;
        public var point:Point;
    }
}

这样需要写两条语句才能完全把Test序列化
registerClassAlias("point",Point);
registerClassAlias("test",Test)

此示例使用 registerClassAlias() 函数为 ExampleClass 注册一个别名 ( com.example.eg )。 由于为类注册了别名,因此可以将对象作为 ExampleClass 的实例反序列化,且代码将输出 true。 如果删除 registerClassAlias() 调用,则代码将输出 false。

package {
    import flash.display.Sprite;
    import flash.net.registerClassAlias;
    import flash.utils.ByteArray;

    public class RegisterClassAliasExample extends Sprite {
        public function RegisterClassAliasExample() {
            registerClassAlias("com.example.eg", ExampleClass);
            var eg1:ExampleClass = new ExampleClass();
            var ba:ByteArray = new ByteArray();
            ba.writeObject(eg1);
            ba.position = 0;
            var eg2:* = ba.readObject();
            trace(eg2 is ExampleClass); // true
        }
    }
}

class ExampleClass {}

      另外有一种转换方式,未亲身测试,先抄录下:
http://hi.baidu.com/menglinxi_a/blog/item/cf75834c82061ef2d72afcc7.html
将通用对象转换为类实例
http://www.darronschall.com/weblog/2006/10/convert-generic-objects-into-class-instances.cfm

大意是有一个Object对象的实例myBook,它有两个属性,name,price
我们有一个类Book,如何将myBook转换为Book呢?
注意myBook是Object类型的,无法Book(myBook)这样进行强制转换
伟大的作者在看到无数条类似问题后,给出了他的解决方案
var book:Book = ObjectTranslator.objectToInstance( myBook, Book ) as Book;
多么简洁,多么强大!!

This questionhas comeupa lotonFlexCodersrecently, so I wanted to offer to the community a generic solution to convert plain old vanilla objects into full-fledged class instances.

I had originally developed this solution to be used with theJSON library that I made for the Adobe Labs Corelib project, but it's really an all-purpose solution. Essentially, my utility method allows you to turn any remote service that returns plain old ActionScript objects (like JSON, WebServices, etc) into a service that returns typed class instances, much like RemoteObject.

This makes it easier to employ the ValueObject pattern... instead of getting back an object with some properties attached, I can convert that object into, say, a Book ValueObject. The Book then is easier to work with because I get IDE and compiler support from strong typing, and it also speeds up the code execution since accessing values in typed objects executes faster than in non-typed objects.

You can download my ObjectTranslator, and its test cases, here. (MIT License)

Usage is as follows:

import com.darronschall.examples.vo.Book;
import com.darronschall.serialization.ObjectTranslator;
// Define an object with properties that mimic the variable names
// inside of the Book class
var bookObj:Object = { title: "My Book title", pageCount: 10, inLibrary: true };
// Convert the generic object into an instance of the Book class
var book:Book = ObjectTranslator.objectToInstance( bookObj, Book ) as Book;

Yup, it's really that simple.

Unfortunately, things get a little more complicated when you have nested ValueObjects. I didn't take the time to make my method recursive, so it's up to you to first convert the nested objects into instances, and then convert the top level object into an instance. It's a little more work that can avoided by some recursion. I've outlined what the algorithm would look like inside of the code, I just haven't had the time to write it yet.

import com.darronschall.examples.vo.Book;
import com.darronschall.examples.vo.Student;
import com.darronschall.serialization.ObjectTranslator;
var studentObj:Object = { firstName: "test first", lastName: "test last", favoriteBook: { title: "Favorite Book!" } };
// First we need to convert the nested objects to classes studentObj.
favoriteBook = ObjectTranslator.objectToInstance( studentObj.favoriteBook, Book );
// Convert the student object to a Student class
var student:Student = ObjectTranslator.objectToInstance( studentObj, Student ) as Student;

So, to summarize, the objectToInstance method allows JSON and WebService services to return true class instances from the server, making them behave like RemoteObject and allowing developers to more easily employ the ValueObject pattern. Use the objectToInstance method on the object that the service returns, and then use the converted instance elsewhere in your code.

Those who are curious about the implementation will get a kick out of the simplicity of my algorithm. Essentially, all I'm doing is constructing an AMF packet with the class name and the object property values, then doing a byteArray.readObject() to convert the AMF packet into a class instance. The code is fairly well commented so you can follow along easily. I'd like to think this is one of those "so simple it's brilliant" type of moments...

Have fun, and let me know if you run into any issues!


如果鸟语生疏的话,直接看代码吧
You can download my ObjectTranslator, and its test cases, here. (MIT License)

那么这个有什么用呢?
比如,我现在在开发一个基于AIR+sqlite的东东,从sqlite返回的每行数据被封装在一个Object类型的实例中,但是针对每张表我都建立了相关的VO,将这个Object转换为VO就是比较有意思的事情了,幸好有作者的无私奉献,终于能少死一些脑细胞了。
同样的,在做Flex+WebService的时候,返回的数据可能是Object或者ObjectProxy,那么用这个方法可以很轻松的将其转换为我们所需要的类型。
Enjoy!!

      关于类型转换:
假设有一个类叫做Class1,我们声明了一个它的对象 c1,如果想要将它转换成Class2类型,只要这样写:

Class2(c1);

在AS3中你依然可以这样写,但是AS3 中提供了一个新的操作符: as ,并且推荐使用as 进行强制转换,上述的例子用 as 操作符实现就是这样:

c1 as Class2;

使用 as 操作符有几个好处:

1.它的效果和第一种方法是一样的。
2.如果类型不兼容无法转换,就会返回null,而不是出错。这样你就可以自定义错误的时候该做什么。
3.没有运行时错误(Run Time Error)提示。

不过有些时候我在使用 as 的时候并不能达到强制转换的目的,而使用第一种方法则可以。为什么 as 操作符有时候会不好用呢?在AS3.0类库中最高层类(Top Level classes)之间进行强制转换时, as 操作符是不起作用的。比如,假如你想要将一个String 类型的字符串 str 转换成 Number 类型的数字 num 时,可能想要这样写:

num = str as Number;

这样写是没有用的,你只能通过第一种方法来达到强制转换的目的:

num = Number(str);

      ok,最后感慨下:万恶的社会啊!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值