`
jinnianshilongnian
  • 浏览: 21424127 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2403122
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2996146
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5630387
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257181
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1592644
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248792
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5845630
Group-logo
跟我学Nginx+Lua开...
浏览量:697465
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:779839
社区版块
存档分类
最新评论

第四章 Controller接口控制器详解(3)——跟着开涛学SpringMVC

阅读更多

4.11、AbstractWizardFormController

向导控制器类提供了多步骤(向导)表单的支持(如完善个人资料时分步骤填写基本信息、工作信息、学校信息等)

假设现在做一个完善个人信息的功能,分三个页面展示:

1、页面1完善基本信息;

2、页面2完善学校信息;

3、页面3完善工作信息。

这里我们要注意的是当用户跳转到页面2时页面1的信息是需要保存起来的,还记得AbstractFormController中的sessionForm吗? 如果为true则表单数据存放到session中,哈哈,AbstractWizardFormController就是使用了这个特性。


向导中的页码从0开始;

PARAM_TARGET = "_target"

用于选择向导中的要使用的页面参数名前缀,如“_target0”则选择第0个页面显示,即图中的“wizard/baseInfo”,以此类推,如“_target1”将选择第1页面,要得到的页码为去除前缀“_target”后的数字即是;

PARAM_FINISH = "_finish"

如果请求参数中有名为“_finish”的参数,表示向导成功结束,将会调用processFinish方法进行完成时的功能处理;

PARAM_CANCEL = "_cancel"

如果请求参数中有名为“_cancel”的参数,表示向导被取消,将会调用processCancel方法进行取消时的功能处理;

向导中的命令对象:

向导中的每一个步骤都会把相关的参数绑定到命令对象,该表单对象默认放置在session中,从而可以跨越多次请求得到该命令对象。

 

接下来具体看一下如何使用吧。

(1、修改我们的模型数据以支持多步骤提交: 

 

Java代码  
  1. public class UserModel {  
  2.     private String username;  
  3.     private String password;  
  4.     private String realname; //真实姓名  
  5.     private WorkInfoModel workInfo;  
  6.     private SchoolInfoModel schoolInfo;  
  7.     //省略getter/setter  
  8. }  

 

Java代码  
  1. public class SchoolInfoModel {  
  2.     private String schoolType; //学校类型:高中、中专、大学  
  3.     private String schoolName; //学校名称  
  4.     private String specialty; //专业  
  5. //省略getter/setter  
  6. }  

 

Java代码  
  1. public class WorkInfoModel {  
  2.     private String city; //所在城市  
  3.     private String job; //职位  
  4.     private String year; //工作年限  
  5. //省略getter/setter  
  6. }  

 

(2、控制器

 

Java代码  
  1. package cn.javass.chapter4.web.controller;  
  2. //省略import  
  3. public class InfoFillWizardFormController extends AbstractWizardFormController {      
  4.     public InfoFillWizardFormController() {  
  5.         setCommandClass(UserModel.class);  
  6.         setCommandName("user");  
  7.     }  
  8.     protected Map referenceData(HttpServletRequest request, int page) throws Exception {  
  9.         Map map = new HashMap();  
  10.         if(page==1) { //如果是填写学校信息页 需要学校类型信息  
  11.             map.put("schoolTypeList", Arrays.asList("高中", "中专", "大学"));  
  12.         }  
  13.         if(page==2) {//如果是填写工作信息页 需要工作城市信息  
  14.             map.put("cityList", Arrays.asList("济南", "北京", "上海"));  
  15.         }  
  16.         return map;  
  17.     }     
  18.     protected void validatePage(Object command, Errors errors, int page) {  
  19.         //提供每一页数据的验证处理方法  
  20.     }  
  21.     protected void postProcessPage(HttpServletRequest request, Object command, Errors errors, int page) throws Exception {  
  22.         //提供给每一页完成时的后处理方法  
  23.     }  
  24.     protected ModelAndView processFinish(HttpServletRequest req, HttpServletResponse resp, Object command, BindException errors) throws Exception {  
  25.         //成功后的处理方法  
  26.         System.out.println(command);  
  27.         return new ModelAndView("redirect:/success");  
  28.     }  
  29.     protected ModelAndView processCancel(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {  
  30.         //取消后的处理方法  
  31.         System.out.println(command);  
  32.         return new ModelAndView("redirect:/cancel");  
  33.     }  
  34. }  

 

page页码:是根据请求中以“_target”开头的参数名来确定的,如“_target0”,则页码为0;

referenceData提供每一页需要的表单支持对象,如完善学校信息需要学校类型,page页码从0开始(而且根据请求参数中以“_target”开头的参数来确定当前页码,如_target1,则page=1);

validatePage验证当前页的命令对象数据,验证应根据page页码来分步骤验证;

postProcessPage验证成功后的后处理;

processFinish成功时执行的方法,此处直接重定向到/success控制器(详见CancelController);

processCancel取消时执行的方法,此处直接重定向到/cancel控制器(详见SuccessController);

 

其他需要了解:

allowDirtyBack和allowDirtyForward决定在当前页面验证失败时,是否允许向导前移和后退,默认false不允许;

onBindAndValidate(HttpServletRequest request, Object command, BindException errors, int page)允许覆盖默认的绑定参数到命令对象和验证流程。

(3、spring配置文件(chapter4-servlet.xml

 

Java代码  
  1. <bean name="/infoFillWizard"   
  2. class="cn.javass.chapter4.web.controller.InfoFillWizardFormController">  
  3.     <property name="pages">  
  4.         <list>  
  5.             <value>wizard/baseInfo</value>  
  6.             <value>wizard/schoolInfo</value>  
  7.             <value>wizard/workInfo</value>  
  8.        </list>  
  9.     </property>  
  10. </bean>      

 

pages表示向导中每一个步骤的逻辑视图名,当InfoFillWizardFormController的page=0,则将会选择“wizard/baseInfo”,以此类推,从而可以按步骤选择要展示的视图。

 

(4、向导中的每一步视图

(4.1、基本信息页面(第一步) baseInfo.jsp 

 

Java代码  
  1. <form method="post">  
  2. 真实姓名:<input type="text" name="realname" value="${user.realname}"><br/>  
  3. <input type="submit" name="_target1" value="下一步"/>  
  4. </form>  

 

当前页码为0

name="_target1"表示向导下一步要显示的页面的页码为1;

 

(4.2、学校信息页面(第二步) schoolInfo.jsp

 

Java代码  
  1. <form method="post">  
  2. 学校类型:<select name="schoolInfo.schoolType">  
  3.   <c:forEach items="${schoolTypeList }" var="schoolType">  
  4.    <option value="${schoolType }"   
  5.        <c:if test="${user.schoolInfo.schoolType eq schoolType}">  
  6.            selected="selected"  
  7.        </c:if>  
  8.    >  
  9.        ${schoolType}  
  10.    </option>  
  11.   </c:forEach>  
  12. </select><br/>  
  13. 学校名称:<input type="text" name="schoolInfo.schoolName" value="${user.schoolInfo.schoolName}"/><br/>  
  14. 专业:<input type="text" name="schoolInfo.specialty" value="${user.schoolInfo.specialty}"/><br/>  
  15. <input type="submit" name="_target0" value="上一步"/>  
  16. <input type="submit" name="_target2" value="下一步"/>  
  17. </form>  

 

(4.3、工作信息页面(第三步) workInfo.jsp

 

Java代码  
  1. <form method="post">  
  2. 所在城市:<select name="workInfo.city">  
  3.   <c:forEach items="${cityList }" var="city">  
  4.    <option value="${city }"   
  5.        <c:if test="${user.workInfo.city eq city}">selected="selected"</c:if>  
  6.    >  
  7.      ${city}  
  8.    </option>  
  9.   </c:forEach>  
  10. </select><br/>  
  11. 职位:<input type="text" name="workInfo.job" value="${user.workInfo.job}"/><br/>  
  12. 工作年限:<input type="text" name="workInfo.year" value="${user.workInfo.year}"/><br/>  
  13. <input type="submit" name="_target1" value="上一步"/>  
  14. <input type="submit" name="_finish" value="完成"/>  
  15. <input type="submit" name="_cancel" value="取消"/>  
  16. </form>  

 

当前页码为2

name="_target1":上一步,表示向导上一步要显示的页面的页码为1;

name="_finish":向导完成,表示向导成功,将会调用向导控制器的processFinish方法

name="_cancel":向导取消,表示向导被取消,将会调用向导控制器的processCancel方法

 

到此向导控制器完成,此处的向导流程比较简单,如果需要更复杂的页面流程控制,可以选择使用Spring Web Flow框架。

 

4.12、ParameterizableViewController

参数化视图控制器,不进行功能处理(即静态视图),根据参数的逻辑视图名直接选择需要展示的视图。 

 

Java代码  
  1. <bean name="/parameterizableView"   
  2. class="org.springframework.web.servlet.mvc.ParameterizableViewController">  
  3. <property name="viewName" value="success"/>  
  4. </bean>  

 

该控制器接收到请求后直接选择参数化的视图,这样的好处是在配置文件中配置,从而避免程序的硬编码,比如像帮助页面等不需要进行功能处理,因此直接使用该控制器映射到视图。

4.13、AbstractUrlViewController

提供根据请求URL路径直接转化为逻辑视图名的支持基类,即不需要功能处理,直接根据URL计算出逻辑视图名,并选择具体视图进行展示:

urlDecode是否进行url解码,不指定则默认使用服务器编码进行解码(如Tomcat默认ISO-8859-1);

urlPathHelper用于解析请求路径的工具类,默认为org.springframework.web.util.UrlPathHelper。

 

UrlFilenameViewController是它的一个实现者,因此我们应该使用UrlFilenameViewController。

 

4.14、UrlFilenameViewController

将请求的URL路径转换为逻辑视图名并返回的转换控制器,即不需要功能处理,直接根据URL计算出逻辑视图名,并选择具体视图进行展示:

 

根据请求URL路径计算逻辑视图名; 

 

Java代码  
  1. <bean name="/index1/*"   
  2. class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>  
  3. <bean name="/index2/**"   
  4. class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>  
  5. <bean name="/*.html"   
  6. class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>  
  7. <bean name="/index3/*.html"   
  8. class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>  

 

/index1/*可以匹配/index1/demo,但不匹配/index1/demo/demo,如/index1/demo逻辑视图名为demo;

/index2/**可以匹配/index2路径下的所有子路径,如匹配/index2/demo,或/index2/demo/demo,“/index2/demo”的逻辑视图名为demo,而“/index2/demo/demo”逻辑视图名为demo/demo;

/*.html可以匹配如/abc.html,逻辑视图名为abc,后缀会被删除(不仅仅可以是html);

/index3/*.html可以匹配/index3/abc.html,逻辑视图名也是abc;

 

上述模式为Spring Web MVC使用的Ant-style 模式进行匹配的:

 

Java代码  
  1. ?    匹配一个字符,如/index? 可以匹配 /index1 , 但不能匹配 /index 或 /index12  
  2. *    匹配零个或多个字符,如/index1/*,可以匹配/index1/demo,但不匹配/index1/demo/demo 
  3. **   匹配零个或多个路径,如/index2/**:可以匹配/index2路径下的所有子路径,如匹配/index2/demo,或/index2/demo/demo 
  4.  
  5. 如果我有如下模式,那Spring该选择哪一个执行呢?当我的请求为“/long/long”时如下所示: 
  6. /long/long 
  7. /long/**/abc  
  8. /long/** 
  9. /** 
  10. Spring的AbstractUrlHandlerMapping使用:最长匹配优先; 
  11. 如请求为“/long/long” 将匹配第一个“/long/long”,但请求“/long/acd” 则将匹配 “/long/**”,如请求“/long/aa/abc”则匹配“/long/**/abc”,如请求“/abc”则将匹配“/**”  

 

UrlFilenameViewController还提供了如下属性:

prefix生成逻辑视图名的前缀;

suffix生成逻辑视图名的后缀;

 

Java代码  
  1. protected String postProcessViewName(String viewName) {  
  2.         return getPrefix() + viewName + getSuffix();  
  3. }  

 

Java代码  
  1. <bean name="/*.htm" class="org.springframework.web.servlet.mvc.UrlFilenameViewController">  
  2.         <property name="prefix" value="test"/>  
  3.         <property name="suffix" value="test"/>  
  4. </bean>  

 

prefix=“test”,suffix=“test,如上所示的/*.htm可以匹配如/abc.htm,但逻辑视图名将变为testabctest。

 


私塾在线学习网
原创内容(http://sishuok.com

原创内容,转载请注明私塾在线【http://sishuok.com/forum/blogPost/list/5254.html

  • 大小: 55.4 KB
32
15
分享到:
评论
28 楼 lwkjob 2012-12-10  
jinnianshilongnian 写道
lwkjob 写道
jinnianshilongnian 写道
lwkjob 写道
AbstractWizardFormController请问这个类已经过时了 ,有神马类可以替代吗?我找了文档,但是没找到,或者是我不会找,请指教谢谢

这个没有 请参考后边注解我写的例子

注解的我都看了,但是没有发现有这中需求的地方?或者你点下哪一节,我再去仔细看看谢谢

请参考 第六章源代码中的cn.javass.chapter6.web.controller.paramtype.WizardFormController 
http://jinnianshilongnian.iteye.com/blog/1683388

没在文章中出现,不好意思

灰常谢谢
27 楼 jinnianshilongnian 2012-12-10  
lwkjob 写道
jinnianshilongnian 写道
lwkjob 写道
AbstractWizardFormController请问这个类已经过时了 ,有神马类可以替代吗?我找了文档,但是没找到,或者是我不会找,请指教谢谢

这个没有 请参考后边注解我写的例子

注解的我都看了,但是没有发现有这中需求的地方?或者你点下哪一节,我再去仔细看看谢谢

请参考 第六章源代码中的cn.javass.chapter6.web.controller.paramtype.WizardFormController 
http://jinnianshilongnian.iteye.com/blog/1683388

没在文章中出现,不好意思
26 楼 lwkjob 2012-12-10  
jinnianshilongnian 写道
lwkjob 写道
AbstractWizardFormController请问这个类已经过时了 ,有神马类可以替代吗?我找了文档,但是没找到,或者是我不会找,请指教谢谢

这个没有 请参考后边注解我写的例子

注解的我都看了,但是没有发现有这中需求的地方?或者你点下哪一节,我再去仔细看看谢谢
25 楼 jinnianshilongnian 2012-12-10  
lwkjob 写道
AbstractWizardFormController请问这个类已经过时了 ,有神马类可以替代吗?我找了文档,但是没找到,或者是我不会找,请指教谢谢

这个没有 请参考后边注解我写的例子
24 楼 lwkjob 2012-12-10  
AbstractWizardFormController请问这个类已经过时了 ,有神马类可以替代吗?我找了文档,但是没找到,或者是我不会找,请指教谢谢
23 楼 jinnianshilongnian 2012-09-12  
那家渔村 写道
jinnianshilongnian 写道
那家渔村 写道
jinnianshilongnian 写道
那家渔村 写道
  我认为Class对象也存在于Heap中。当classloader在load一个class时,会将该class的类型信息的数据结构(例如方法表等)加载到方法区中,并且在堆中创建一个Class对象来代表该类型信息。
  不知道我的理解是不是有误。

class对象存放在方法区 不是堆


过不了多久你就会认同我的观点亦或者我认同你的!

嗯  呵呵 可以去看下内存分配的知识


不知道我们所说的在"class对象"这个概念是不是同一个。我指的class对象是类似这种:
vo是一个VO类的对象实例。 我指的class对象是这个:VO.class 或者 vo.getClass();

是一个概念 
22 楼 那家渔村 2012-09-12  
jinnianshilongnian 写道
那家渔村 写道
jinnianshilongnian 写道
那家渔村 写道
  我认为Class对象也存在于Heap中。当classloader在load一个class时,会将该class的类型信息的数据结构(例如方法表等)加载到方法区中,并且在堆中创建一个Class对象来代表该类型信息。
  不知道我的理解是不是有误。

class对象存放在方法区 不是堆


过不了多久你就会认同我的观点亦或者我认同你的!

嗯  呵呵 可以去看下内存分配的知识


不知道我们所说的在"class对象"这个概念是不是同一个。我指的class对象是类似这种:
vo是一个VO类的对象实例。 我指的class对象是这个:VO.class 或者 vo.getClass();
21 楼 jinnianshilongnian 2012-09-12  
那家渔村 写道
jinnianshilongnian 写道
那家渔村 写道
  我认为Class对象也存在于Heap中。当classloader在load一个class时,会将该class的类型信息的数据结构(例如方法表等)加载到方法区中,并且在堆中创建一个Class对象来代表该类型信息。
  不知道我的理解是不是有误。

class对象存放在方法区 不是堆


过不了多久你就会认同我的观点亦或者我认同你的!

嗯  呵呵 可以去看下内存分配的知识
20 楼 那家渔村 2012-09-12  
jinnianshilongnian 写道
那家渔村 写道
  我认为Class对象也存在于Heap中。当classloader在load一个class时,会将该class的类型信息的数据结构(例如方法表等)加载到方法区中,并且在堆中创建一个Class对象来代表该类型信息。
  不知道我的理解是不是有误。

class对象存放在方法区 不是堆


过不了多久你就会认同我的观点亦或者我认同你的!
19 楼 jinnianshilongnian 2012-09-12  
那家渔村 写道
  我认为Class对象也存在于Heap中。当classloader在load一个class时,会将该class的类型信息的数据结构(例如方法表等)加载到方法区中,并且在堆中创建一个Class对象来代表该类型信息。
  不知道我的理解是不是有误。

class对象存放在方法区 不是堆
18 楼 那家渔村 2012-09-12  
  我认为Class对象也存在于Heap中。当classloader在load一个class时,会将该class的类型信息的数据结构(例如方法表等)加载到方法区中,并且在堆中创建一个Class对象来代表该类型信息。
  不知道我的理解是不是有误。
17 楼 jinnianshilongnian 2012-09-12  
只有类定义对象
cmyx2008love 写道
jinnianshilongnian 写道
cmyx2008love 写道
cmyx2008love 写道

如果在方法中,频繁的调用,肯定非常不好;
那能不能把这样
  String pattern = "#,###.##";
  private static final DecimalFormat df = new DecimalFormat(pattern);
 
对象放到类的成员属性中,并且,在方法中调用呢?
如果能,那么DecimalFormat df 对象创建在什么地方,堆?还是常量对象池中?如果放在堆中,因为是static的,那么在类初始化时,就有一个这样的对象,这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?

一直很困惑!

帮我看看,万分感谢!


第一点:
DecimalFormat 不是线程安全的,如果多个线程使用且格式不一样可能造成线程安全问题,如
A线程需要 #,###.##格式
B线程修改成 ###.##格式 就会出现问题,但是如果不修改格式就没有问题的。

第二点:
只有类定义对象、常量字符串等才放在常量池
只要通过new的都是放在堆中

第三点
static变量/块是在类加载时初始化,且仅仅初始化一次, static变量可以复用且每个classloader一个实例(减少了实例数量)

第四点
  如 class A{
             static B b = new B();
      }
     
     static的b伴随A类定义存放在常量池,,但new B() 肯定在堆中

第五点
   你不需要为【这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?】 担心,因为如果你不用会被垃圾回收。
  
   当遇到性能问题再来考虑这个问题。


谢谢,明白了!  


对于你说的第二点: "类定义对象"指的是Class对象还是别的什么?
是的
16 楼 那家渔村 2012-09-12  
只有类定义对象
jinnianshilongnian 写道
cmyx2008love 写道
cmyx2008love 写道

如果在方法中,频繁的调用,肯定非常不好;
那能不能把这样
  String pattern = "#,###.##";
  private static final DecimalFormat df = new DecimalFormat(pattern);
 
对象放到类的成员属性中,并且,在方法中调用呢?
如果能,那么DecimalFormat df 对象创建在什么地方,堆?还是常量对象池中?如果放在堆中,因为是static的,那么在类初始化时,就有一个这样的对象,这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?

一直很困惑!

帮我看看,万分感谢!


第一点:
DecimalFormat 不是线程安全的,如果多个线程使用且格式不一样可能造成线程安全问题,如
A线程需要 #,###.##格式
B线程修改成 ###.##格式 就会出现问题,但是如果不修改格式就没有问题的。

第二点:
只有类定义对象、常量字符串等才放在常量池
只要通过new的都是放在堆中

第三点
static变量/块是在类加载时初始化,且仅仅初始化一次, static变量可以复用且每个classloader一个实例(减少了实例数量)

第四点
  如 class A{
             static B b = new B();
      }
     
     static的b伴随A类定义存放在常量池,,但new B() 肯定在堆中

第五点
   你不需要为【这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?】 担心,因为如果你不用会被垃圾回收。
  
   当遇到性能问题再来考虑这个问题。


谢谢,明白了!  


对于你说的第二点: "类定义对象"指的是Class对象还是别的什么?
15 楼 jinnianshilongnian 2012-08-09  
Rejoy 写道
都用注解了。。。怎么还用这么原始的方式啊?


这是遗留问题, 后续会有
14 楼 Rejoy 2012-08-09  
都用注解了。。。怎么还用这么原始的方式啊?
13 楼 cmyx2008love 2012-08-09  
cmyx2008love 写道
cmyx2008love 写道

如果在方法中,频繁的调用,肯定非常不好;
那能不能把这样
  String pattern = "#,###.##";
  private static final DecimalFormat df = new DecimalFormat(pattern);
 
对象放到类的成员属性中,并且,在方法中调用呢?
如果能,那么DecimalFormat df 对象创建在什么地方,堆?还是常量对象池中?如果放在堆中,因为是static的,那么在类初始化时,就有一个这样的对象,这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?

一直很困惑!

帮我看看,万分感谢!


第一点:
DecimalFormat 不是线程安全的,如果多个线程使用且格式不一样可能造成线程安全问题,如
A线程需要 #,###.##格式
B线程修改成 ###.##格式 就会出现问题,但是如果不修改格式就没有问题的。

第二点:
只有类定义对象、常量字符串等才放在常量池
只要通过new的都是放在堆中

第三点
static变量/块是在类加载时初始化,且仅仅初始化一次, static变量可以复用且每个classloader一个实例(减少了实例数量)

第四点
  如 class A{
             static B b = new B();
      }
     
     static的b伴随A类定义存放在常量池,,但new B() 肯定在堆中

第五点
   你不需要为【这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?】 担心,因为如果你不用会被垃圾回收。
  
   当遇到性能问题再来考虑这个问题。


谢谢,明白了!  
12 楼 jinnianshilongnian 2012-08-09  
cmyx2008love 写道

对象放到类的成员属性中,并且,在方法中调用呢?
如果能,那么DecimalFormat df 对象创建在什么地方,堆?还是常量对象池中?如果放在堆中,因为是static的,那么在类初始化时,就有一个这样的对象,这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?


当然你可以选择实例池 来做,,如Common-pool 但没必要; 如果DecimalFormat的格式不会改,可以做成单例使用(没有多线程修改格式字符串,不存在线程安全问题)
11 楼 jinnianshilongnian 2012-08-09  
cmyx2008love 写道

如果在方法中,频繁的调用,肯定非常不好;
那能不能把这样
  String pattern = "#,###.##";
  private static final DecimalFormat df = new DecimalFormat(pattern);
 
对象放到类的成员属性中,并且,在方法中调用呢?
如果能,那么DecimalFormat df 对象创建在什么地方,堆?还是常量对象池中?如果放在堆中,因为是static的,那么在类初始化时,就有一个这样的对象,这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?

一直很困惑!

帮我看看,万分感谢!


第一点:
DecimalFormat 不是线程安全的,如果多个线程使用且格式不一样可能造成线程安全问题,如
A线程需要 #,###.##格式
B线程修改成 ###.##格式 就会出现问题,但是如果不修改格式就没有问题的。

第二点:
只有类定义对象、常量字符串等才放在常量池
只要通过new的都是放在堆中

第三点
static变量/块是在类加载时初始化,且仅仅初始化一次, static变量可以复用且每个classloader一个实例(减少了实例数量)

第四点
  如 class A{
             static B b = new B();
      }
     
     static的b伴随A类定义存放在常量池,,但new B() 肯定在堆中

第五点
   你不需要为【这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?】 担心,因为如果你不用会被垃圾回收。
  
   当遇到性能问题再来考虑这个问题。

10 楼 cmyx2008love 2012-08-09  
cmyx2008love 写道
等了好久终于等到今天!!
哎,这水平,哎!强烈的..........羡慕嫉妒恨!


哪敢BS呀,哎羡慕的不行了,我的水平能跟在你的后面就很不错了!

随便问个问题哈,老大!

假如现在有这样一个方法:
public static String toMoneyStyle(double number) {
		String pattern = "#,###.##";
		DecimalFormat df = new DecimalFormat(pattern);
		return df.format(number);
	}
   

如果在方法中,频繁的调用,肯定非常不好;
那能不能把这样
  String pattern = "#,###.##";
  private static final DecimalFormat df = new DecimalFormat(pattern);
 
对象放到类的成员属性中,并且,在方法中调用呢?
如果能,那么DecimalFormat df 对象创建在什么地方,堆?还是常量对象池中?如果放在堆中,因为是static的,那么在类初始化时,就有一个这样的对象,这样是不是在项目中多了,容易引起【相对的】无用对象太多,而导致内存问题呢?

一直很困惑!

帮我看看,万分感谢!
9 楼 jinnianshilongnian 2012-08-09  
cmyx2008love 写道
等了好久终于等到今天!!
哎,这水平,哎!强烈的..........羡慕嫉妒恨!

cmyx2008love 写道
等了好久终于等到今天!!
哎,这水平,哎!强烈的..........羡慕嫉妒恨!


你是夸我呢 还是BS我呢   谢谢啊

相关推荐

    源代码下载 第五章 处理器拦截器详解——跟着开涛学SpringMVC

    NULL 博文链接:https://jinnianshilongnian.iteye.com/blog/1679570

    跟着开涛学SpringMVC

    跟着开涛学SpringMVC,很好的MVC教程,简单易懂,PDF高清版本

    SpringMvc开涛.rar

    PDF,源代码 开涛学SpringMVC 第一章源...第四章 Controller接口控制器详解 源代码下载 第五章 处理器拦截器详解——跟着开涛学SpringMVC 第六章 注解式控制器详解 第七章 注解式控制器的数据验证、类型转换及格式化

    跟着开涛学SpringMVC.pdf

    跟开涛学springmvc pdf电子文档版 适合学习springmvc 非常好的教程

    跟我学SpringMVC 教程

    第四章 Controller接口控制器详解(4) 第四章 Controller接口控制器详解(5) 第四章 Controller接口控制器详解(6) 第五章 处理器拦截器详解 第六章 注解式控制器详解 注解式控制器运行流程及处理器定义 第...

    跟开涛学 SpringMVC

    跟开涛学 SpringMVC跟开涛学 SpringMVC跟开涛学 SpringMVC跟开涛学 SpringMVC

    跟我学SpringMVC

    第四章 Controller接口控制器详解(4) 第四章 Controller接口控制器详解(5) 第四章 Controller接口控制器详解(6) 第五章 处理器拦截器详解 第六章 注解式控制器详解 注解式控制器运行流程及处理器定义 第六章 ...

    SpringMVC教程

    第四章 Controller接口控制器详解(3).pdf 第四章 Controller接口控制器详解 (4).pdf 第四章 Controller接口控制器详解 (5).pdf 第四章 Controller接口控制器详解 (6).pdf 第四章 Controller接口控制器详解...

    跟开涛学SpringMVC-高清版

    跟开涛学SpringMVC-高清版,找了好久的,分享给大家。

    Spring MVC学习(四)-------Controller接口控制器详解1

    Spring MVC学习(四)-------Controller接口控制器详解1

    跟开涛学SpringMVC(4.6)Controller接

    跟开涛学SpringMVC(4.6)Controller接口控制器详解(6)Java开发Java经验技巧共10页.pdf.zip

    跟开涛学SpringMVC源代码

    跟开涛学SpringMVC源代码汇总

    跟开涛学SpringMVC

    跟开涛学SpringMVC 高清 带书签 pdf 通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText和POI。Spring MVC 框架并不知道使用的视图,所以...

    跟开涛学SpringMVC(4.3)Controller接

    跟开涛学SpringMVC(4.3)Controller接口控制器详解(3)Java开发Java经验技巧共9页.pdf.zip

    跟开涛学习springmvc spring 3 pdf

    跟开涛学习springmvc spring 3 pdf ,非常好的资料。我将原文档的spring合并为一份,查看更方便一些。

    跟开涛学springmvc

    开涛写的中文springmvc开发文档 , 初学者可以下载学习,或者当做字典用。

    跟开涛学SpringMVC(5)处理器拦截器详解Java开

    跟开涛学SpringMVC(5)处理器拦截器详解Java开发Java经验技巧共13页.pdf.zip

    SpringMVC入门——跟开涛学SpringMVC

    SpringWebMVC是一种基于Java的实现了WebMVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行...应用控制器其实拆为处理器映射器(HandlerMapping)进行处理器管理和视图解析器(ViewResolv

Global site tag (gtag.js) - Google Analytics