基本上我的意思是这样的:
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” - 因为教授也这样做。 :)
答案 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上。