在对JSP隐式对象的属性进行转换时,我应该添加try / catch吗?

时间:2010-06-13 11:10:55

标签: java jsp casting

基本上我的意思是这样的:

List<String[]> routes = (List<String[]>)application.getAttribute("routes");

对于上面的代码,它尝试从JSP隐式对象 - 应用程序中获取名为“routes”的属性。但众所周知,在这行代码之后,路由可能很好地包含null - 这意味着该应用程序没有名为“routes”的属性。

这是否是“使用Java编译”在Java中的良好编程实践?

基本上我试图避免例如java.io.InvalidCastException

之类的异常

我认为,当这种语言没有引入泛型类型时,这样的东西更像是Java 1.4的“遗产”。所以我猜应用程序属性中存储的所有内容都是对象(类似于传统的ArrayList)。当你做“向下倾斜”时,可能会有无效的演员阵容。

在这种情况下你会做什么?

更新

刚刚发现虽然在隐式对象应用程序中我存储了一个String数组列表,但是当我这样做时:

List<double[]> routes = (List<double[]>)application.getAttribute("routes");

它不会产生任何错误......我感觉不舒服......

即使使用此代码:

out.print(routes.get(0));

它打印出一些奇怪的东西:

[Ljava.lang.String;@18b352f

我是否打印了“String指针”?我终于可以得到这样的例外:

out.print(routes.get(0)[1]);

有错误:

java.lang.ClassCastException: [Ljava.lang.String;

因为我是添加应用程序属性的,所以我知道它应该转换为哪种类型。我觉得这不够“好”,如果我忘记了确切类型怎么办? 我知道在某些情况下会发生这种情况,例如在JSP / Servlet中进行会话属性的转换时。有更好的方法吗?

在你说:“OMG,为什么你不使用Servlets ???”之后,我应该证明我的理由: - 因为我的单身很糟糕,它的服务器只能用JSP生成的Servlet,我不知道我真的想学习如何解决这类问题。 look at my previous question on this ,这是单一的家庭作业,所以我别无选择,忘记所有关于战争,WEB-INF等,但“将所有内容直接编入JSP” - 因为教授也这样做。 :)

2 个答案:

答案 0 :(得分:2)

Java使用类型擦除来存储集合。也就是说,编译器强制执行类型安全,但将集合减少到Objects的集合。因此,当您从bean中提取列表对象时,它是List<Object>而不是List<Double>

因为它是一个集合,你可以获得 nth 元素(正如你所做的那样)。然而,你得到的对象并不是你所期望的。因此,当您从集合中提取一个元素并将其强制转换(到Double而不是String)时,运行时将最终反对。

[Ljava.lang.String;@18b352f是对String数组的引用,顺便说一下。 ('['表示数组)。

出于这个原因(和其他人)我不喜欢存储类型集合的集合。我宁愿创建一个特定的对象类型(一个容器),然后向该对象询问我需要的元素。所以你只需要在从bean中提取对象时抛出一次,然后在这个对象中管理列表中处理双精度数组的复杂性(你可以要求容器对象为你找到元素,提取逻辑/铸造在一个地方等。)

答案 1 :(得分:2)

创建一个类(Application),在ServletContext上存储一次,然后以常规Java样式调用该类的方法。

在该Application类中添加一个方法。

// Make sure that ATTRIBUTE_NAME is somewhat unique.
private final static String ATTRIBUTE_NAME =
    Application.getClass( ).getName( );

List< String > myList;

public saveToAppContext ( ServletContext context )
{
    context.setAttribute( ATTRIBUTE_NAME, this );
}

public static Application getAttribute ( ServletContext context )
{
    return (Application) context.getAttribute( ATTRIBUTE_NAME );
}

// Because you store object in application scope, ensure that
// access methods are thread-safe
//
// This is just an example, you may need something with better
// performance
synchronized List< String > getStringList ( )
{
    return new ArrayList<String>(myList);
}

现在设置ServletContextListener,在加载/卸载ServletContext时初始化并销毁您的Application对象

contextInitialized方法应创建Application对象并将其作为属性保存在ServletContext上。