??xml version="1.0" encoding="utf-8" standalone="yes"?> 在网站中l常需要进行在Uh数的l计。过ȝ一般做法是l合d和退出功能,卛_用户输入用户名密码进行登录的时候计数器?/font>1Q然后当用户点击退出按钮退出系l的时候计数器?/font>1。这U处理方式存在一些缺点,例如Q用h常登录后Q可能会忘记点击退出按钮,而直接关闭浏览器Q导致计数器?/font>1的操作没有及时执行;|站上还l常有一些内Ҏ不需要登录就可以讉K的,在这U情况下也无法用上面的Ҏq行在线人数l计?/font> 1.
package accp.onlinecounter;
2.
public class OnlineCounter {
3.
private static long online = 0;
4.
public static long getOnline() {
5.
return online;
6.
} 7.
public static void raise(){
8.
online++;
9.
} 10.
public static void reduce(){
11.
online--;
12.
}
13.
}
1.
package accp.onlinecounter;
2.
import javax.servlet.http.HttpSessionEvent;
3.
import javax.servlet.http.HttpSessionListener;
4.
public class OnlineCounterListener implements HttpSessionListener {
5.
public void sessionCreated(HttpSessionEvent hse) {
6.
OnlineCounter.raise();
7.
}
8.
public void sessionDestroyed(HttpSessionEvent hse) {
9.
OnlineCounter.reduce();
10.
}
11.
}
1.
<web-app>
2.
…… 3.
<listener>
4.
<listener-class>
5.
accp.OnlineCounterListener
6.
</listener-class>
7.
</listener>
8.
…… 9.
</web-app>
1.
<%@ page language="java" pageEncoding="GB2312" %>
2.
<%@ page import="accp.OnlineCounter" %>
3.
<html> 4.
<head><title>On Line Counert</title></head>
5.
<body bgcolor="#FFFFFF">
6.
On line:<%=OnlineCounter.getOnline()%>
7.
</body>
8.
</html>
与每?Timer 对象相对应的是单个后台线E,用于序地执行所有计时器d。计时器d应该q速完成。如果完成某个计时器d的时间太长,那么它会“独占”计时器的d执行U程。因此,q就可能延迟后箋d的执行,而这些Q务就可能“堆在一?#8221;Qƈ且在上述不友好的d最l完成时才能够被快速连l地执行?
?Timer 对象最后的引用完成后,q且 所有未处理的Q务都已执行完成后Q计时器的Q务执行线E会正常l止Qƈ且成为垃圑֛收的对象Q。但是这可能要很长时间后才发生。默认情况下QQ务执行线Eƈ不作?em>守护U程 来运行,所以它能够L应用E序l止。如果调用者想要快速终止计时器的Q务执行线E,那么调用者应该调用计时器?cancel Ҏ?
如果意外l止了计时器的Q务执行线E,例如调用了它?stop ҎQ那么所有以后对该计时器安排d的尝试都导?IllegalStateExceptionQ就好像调用了计时器?cancel Ҏ一栗?
此类是线E安全的Q多个线E可以共享单?Timer 对象而无需q行外部同步?
此类?/em> 提供实时保证Q它使用 Object.wait(long) Ҏ来安排Q务?
实现注意事项Q此cd扩展到大量同时安排的dQ存在数千个都没有问题)。在内部Q它使用二进制堆来表C其d队列Q所以安排Q务的开销?O(log n)Q其?n 是同时安排的d数?
实现注意事项Q所有构造方法都启动计时器线E?/p>
public class MyListner implements ServletContextListener { public void contextInitialized(ServletContextEvent event1) { } import java.util.Date; public class Str extends TimerTask{ <?xml version="1.0" encoding="UTF-8"?> 原文出处Q?br />
http://blog.csdn.net/feifniao/archive/2007/11/22/1897392.aspx 首先Q如果你?/span>web.xml文g中的配置是这LQ?/span> <context-param> 那么需要在工程下创Z个以applicationContext- 为开头的xml文geg:applicationContext-jobconfig.xml xml的头和结N分跟其他spring配置文g怼Q就不赘qͼ正文如下Q?/span> <bean id="youJobName(cd?/span>)" class="com.******.YourJobClassLocation(cȝ定位)" /> <bean id="doScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> q样的配|几本就可以q{了,但是有一个地方可能是你需要根据你的需求来定的,那就是触发时间?/span> 下面有一些关于时间配|的说明Q?/span>
字段序 允许?/span> 允许的特D字W?/span> U?/span> 0-59 , - * / ?/span> 0-59 , - * / 时 0-23 , - * / 日期 1-31 , - * ? / L W C 月䆾 1-12 或?JAN-DEC , - * / 星期 1-7 或?SUN-SAT , - * ? / L C # q_可选) 留空, 1970-2099 , - * /
我们可以利用Servlet规范中定义的事g监听器(ListenerQ来解决q个问题Q实现更准确的在Uh数统计功能。对每一个正在访问的用户Q?/font>J2EE应用服务器会为其建立一个对应的HttpSession对象。当一个浏览器W一ơ访问网站的时候,J2EE应用服务器会新徏一?/font>HttpSession对象Qƈ触发HttpSession创徏事gQ如果注册了HttpSessionListener事g监听器,则会调用HttpSessionListener事g监听器的sessionCreatedҎ。相反,当这个浏览器讉Kl束时的时候,J2EE应用服务器会销毁相应的HttpSession对象Q触?/font>HttpSession销毁事Ӟ同时调用所注册HttpSessionListener事g监听器的sessionDestroyedҎ?/font>
可见Q对应于一个用戯问的开始和l束Q相应的?/font>sessionCreatedҎ?/font>sessionDestroyedҎ执行。这P我们只需要在HttpSessionListener实现cȝsessionCreatedҎ中让计数器加1Q在sessionDestroyedҎ中让计数器减1Q就L实现了网站在Uh数的l计功能?/font>
下面是利用HttpSessionListener实现在线人数l计的一个例子,q个例子已经在中创Y件的J2EE应用服务?/font>InforWeb中测试通过?/font>
首先Q编写一个简单的计数器,代码如下Q?/span>
然后Q编?/font>HttpSessionListener实现c,在这个实现类?/font>sessionCreatedҎ中调?/font>OnlineCounter?/font>raiseҎQ在sessionDestroyedҎ中调?/font>OnlineCounter?/font>reduceҎQ代码如下:
再然后,把这?/font>HttpSessionListener实现cL册到|站应用中,也就是在|站应用?/font>web.xml中加入如下内容:
OKQ在Uh数统计功能已l实玎ͼ只要?/font>JSP面中加入下面这L脚本p昄但前在线人数了:
]]>
import java.util.Timer;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
private Timer timer=null;
private long start=0;
private long end=1000*60;
timer=new Timer(true);
timer.schedule(new Str(),start,end);
void
schedule(TimerTask task, Date time)
安排在指定的旉执行指定的Q务?/td>
void
schedule(TimerTask task, Date firstTime, long period)
安排指定的Q务在指定的时间开始进行重复的固定延迟执行?/td>
void
schedule(TimerTask task, long delay)
安排在指定gq后执行指定的Q务?/td>
void
schedule(TimerTask task, long delay, long period)
安排指定的Q务从指定的gq后开始进行重复的固定延迟执行
}
public void contextDestroyed(ServletContextEvent event0) {
timer.cancel();// l止此计时器Q丢弃所有当前已安排的Q务?br />
}
import java.util.TimerTask;
public void run() {
System.out.println("定时试成功Q?+(new Date()));
}
}
web.xml加以配置
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class> MyListner</listener-class>
</listener>
------------------------------------------------------------------------------------------------------------
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/applicationContext-*.xml
</param-value>
</context-param>
<bean id="doYourJob(别名)" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="youJobName(cd?/span>)""/>
</property>
<property name="targetMethod">
<value>runMethodName(定时执行的方法名)</value>
</property>
</bean>
<bean id="youJobNameTrigger(触发器别?/span>)" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="doYourJob(别名)""/>
</property>
<property name="cronExpression">
<value>0 0/20 * * * ?(定时的时间配|?/span>)</value>
</property>
</bean>
<property name="triggers">
<list>
<ref local="youJobNameTrigger(触发器别?/span>)"/>
</list>
</property>
</bean>
The '*' character is used to specify all values. For example, "*" in the minute field means "every minute".
“*”字符被用来指定所有的倹{如Q?/span>”*“在分钟的字段域里表示“每分?/span>”?/span>
The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify 'no specific value'. This is useful when you need to specify something in one of the two fileds, but not the other. See the examples below for clarification.
“?”字符只在日期域和星期域中使用。它被用来指?/span>“非明的?/span>”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你׃明白?/span>
月䆾中的日期和星期中的日期这两个元素时互斥的一起应该通过讄一个问?/span>(?)来表明不惌|那个字D?/span>
The '-' character is used to specify ranges For example "10-12" in the hour field means "the hours 10, 11 and 12".
“-”字符被用来指定一个范围。如Q?/span>“10-12”在小时域意味着“10炏V?/span>11炏V?/span>12?/span>”?/span>
The ',' character is used to specify additional values. For example "MON,WED,FRI" in the day-of-week field means "the days Monday, Wednesday, and Friday".
“,”字符被用来指定另外的倹{如Q?/span>“MON,WED,FRI”在星期域里表C?/span>”星期一、星期三、星期五”.
The '/' character is used to specify increments. For example "0/15" in the seconds field means "the seconds 0, 15, 30, and 45". And "5/15" in the seconds field means "the seconds 5, 20, 35, and 50". Specifying '*' before the '/' is equivalent to specifying 0 is the value to start with. Essentially, for each field in the expression, there is a set of numbers that can be turned on or off. For seconds and minutes, the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to 31, and for months 1 to 12. The "/" character simply helps you turn on every "nth" value in the given set. Thus "7/6" in the month field only turns on month "7", it does NOT mean every 6th month, please note that subtlety.
"/"字符用来指定渐增的倹{例?/span>0/15出现在秒字段的时候意味着“在第0Q?/span>15Q?/span>30?/span>45U?/span>”Q的时候被触发Q。?/span>5/15出现在秒字段的时候意味着“在第5Q?/span>20Q?/span>35和第50U?/span>”Q的时候被触发Q?/span>"*/"?/span>"0/"的指定是{h的?/span>
注:当分?/span>+分母的值大于该字段的最大|如在U钟字段出现45/20的时候,表示在第45U以后的?/span>20会触发一ơ,但是20U以后又做另外的时间段以内了,所以该字段?/span>/20卛_效,如改?/span>45/10 则只?/span>W?/span>45 ?/span>55U会执行一ơ?/span>
The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last", but it has different meaning in each of the two fields. For example, the value "L" in the day-of-month field means "the last day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx day of the month" - for example "6L" means "the last friday of the month". When using the 'L' option, it is important not to specify lists, or ranges of values, as you'll get confusing results.
L?/span>‘last’的省略写法可以表C?/span>day-of-month?/span>day-of-week域,但在两个字段中的意思不同,例如day-of-month域中表示一个月的最后一天,
如果?/span>day-of-week域表C?/span>‘7’或?/span>‘SAT’Q如果在day-of-week域中前面加上数字Q它表示一个月的最后几天,例如‘6L’pCZ个月的最后一?/span>
星期五,
The 'W' character is allowed for the day-of-month field. This character is used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify "15W" as the value for the day-of-month field, the meaning is: "the nearest weekday to the 15th of the month". So if the 15th is a Saturday, the trigger will fire on Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. However if you specify "1W" as the value for day-of-month, and the 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not 'jump' over the boundary of a month's days. The 'W' character can only be specified when the day-of-month is a single day, not a range or list of days
.
The 'L' and 'W' characters can also be combined for the day-of-month expression to yield 'LW', which translates to "last weekday of the month".
The '#' character is allowed for the day-of-week field. This character is used to specify "the nth" XXX day of the month. For example, the value of "6#3" in the day-of-week field means the third Friday of the month (day 6 = Friday and "#3" = the 3rd one in the month). Other examples: "2#1" = the first Monday of the month and "4#5" = the fifth Wednesday of the month. Note that if you specify "#5" and there is not 5 of the given day-of-week in the month, then no firing will occur that month.
The 'C' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "calendar". This means values are calculated against the associated calendar, if any. If no calendar is associated, then it is equivalent to having an all-inclusive calendar. A value of "5C" in the day-of-month field means "the first day included by the calendar on or after the 5th". A value of "1C" in the day-of-week field means "the first day included by the calendar on or after sunday".
关于cronExpression的介l?/span>:
字段允许?/span>允许的特D字W?/span>
U?/span> 0-59 , - * /
?/span> 0-59 , - * /
时 0-23 , - * /
日期 1-31 , - * ? / L W C
月䆾 1-12 或?/span> JAN-DEC , - * /
星期 1-7 或?/span> SUN-SAT , - * ? / L C #
q_可选)留空, 1970-2099 , - * /
表达式意?/span>
"0 0 12 * * ?" 每天中午12点触?/span>
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005q的每天上午10:15触发
"0 * 14 * * ?" 在每天下?/span>2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下?/span>2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下?/span>2点到2:55期间和下?/span>6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下?/span>2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下?/span>2:10?/span>2:44触发
"0 15 10 ? * MON-FRI" 周一臛_五的上午10:15触发
"0 15 10 15 * ?" 每月15日上?/span>10:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6L 2002-2005" 2002q至2005q的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上?/span>10:15触发
每天早上6?/span>
0 6 * * *
每两个小?/span>
0 */2 * * *
晚上11点到早上7点之间每两个时Q早上八?/span>
0 23-7/2Q?/span>8 * * *
每个月的4号和每个C拜的礼拜一到礼拜三的早?/span>11?/span>
0 11 4 * 1-3
1?/span>1日早?/span>4?/span>
0 4 1 1 *
quartz的高U特性不仅如?/span>
1 数据库存?/span>
2 集群支持
3 数据库持久化dQ?/span>trigger
4 trigger 的停止,q行
5 d的Q意添?/span>
6 ?/span>corntrigger 更详的d安排
7 U程的内部数据交?/span>
public static Logger getLogger( String name)
通过指定的名字获得记录器Q如果必要的话,则ؓq个名字创徏一个新的记录器?br /> Name一般取本类的名字,比如Q?
static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )
②读取配|文?
当获得了日志记录器之后,W二步将配置Log4j环境Q其语法为:
BasicConfigurator.configure ()Q?自动快速地使用~省Log4j环境?br /> PropertyConfigurator.configure ( String configFilename) Q读取用Java的特性文件编写的配置文g?/p>
例:PropertyConfigurator.configure(".\\src\\log4j.properties")
DOMConfigurator.configure ( String filename ) Q读取XML形式的配|文件?/p>
③插入记录信息(格式化日志信息)
当上两个必要步骤执行完毕Q就可轻村֜使用不同优先U别的日志记录语句插入到您想记录?br /> 志的M ?nbsp;方,其语法如下:
Logger.debug ( Object message ) ;
Logger.info ( Object message ) ;
Logger.warn ( Object message ) ;
Logger.error ( Object message ) ;
在webE序中用log4j注意问题
1?nbsp; ׃jsp或servlet在执行状态时没有当前路径概念Q所有用PropertyConfigurator.configureQStringQ语句找log4j.properties文g时要l出相对于当前jsp或servlet的\径{化成Z个绝对的文gpȝ路径。方法是使用 servletcontext.getrealpath(string)语句。例Q?/p>
//得到当前jsp路径
String prefix = getServletContext().getRealPath("/");
//dlog4j.properties
PropertyConfigurator.configure(prefix+"\\WEB-INF\\log4j.properties");
2、相应的log4j.properties讄某个属性时也要在程序中讄l对路径。例Q?/p>
log4j.appender.R.File属性设|日志文件存放位|。我们可以用d.properties配置文g的方法进行灵z设|?br />
*********************************************************
一个实例:
一Q?br />
配置一个名为log4j.properties 文g,攑ֈ目的src文g下面卛_
log4j.rootLogger= INFO, A1 , R
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
#指定日志文g攄位置
log4j.appender.R.File=D:/env/environment/webEnv/WEB-INF/log4j.log
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
#log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] (%13F:%L) %3x - %m%n
二:
在src下徏一个初始化的servlet让程序启动时加蝲log4j.properties文g
import javax.servlet.http.HttpServlet;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class Log4jInit extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init() {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j");
// if the log4j-init-file is not set, then no point in trying
System.out.println("- Log4j start");
if(file != null) {
PropertyConfigurator.configure(prefix+file);
}
Logger _logger = Logger.getLogger (Log4jInit.class);
_logger.info("- Log4j Test Successfully!");
}
}
三:在web.xml中配|这个Log4jInit .javaq个servlet
<servlet>
<servlet-name>log4jlog4j-init</servlet-name>
<servlet-class>Log4jInit</servlet-class>
<init-param>
<param-name>log4j</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
个h看法Q不一定正?
你是女生Q有没有接触q毛U团
毛线团就是我们实CSerializable接口的对?br />
一个毛U团可以抽成很长的毛U?br />
又可以把很长的毛U卷成毛U团
对应h是
一个巨大的对象可以抽成很简单的文本表达保存h
需要用这个对象的时?br />
再根据这些文本生?br />
Serializable 只是一个标志,让JVM能够知道可以安全的把object转化成上面老兄说的毛线团?br />
你不需要作Mcode?br />
Serializable 对JAVABEANS是必ȝ接口?br />
你不需要作M实现?/p>
序列化是把一个对象的状态写入一个字节流的过E,它执行RMIQRMI允许一台机器上的JAVA对象调用不同机器上的JAVA对象ҎQ对象可以作为参数提供给那个q程ҎQ发送机序列化该对象q传送它Q接收机执行反序列化?br />
序列化和反序列化的关pd表可形成包含循环引用的顺序图表。这是整个序列化的M思想?br />
而Serializable接口属于支持序列化的一个接口,只有一个实现它的对象可以被序列化工具存储和回复QSerializable接口没有定义M成员Q只用来表示一个篏可以被序列化Q若该类可以序列化,那么它的所有子c都可以?br />
下面是关于序列化的一个实例:
[b:a55efb5f91]E序名称QSerializationDemo.java
E序主题Q实现对象的序列化和反序列化
E序说明Q该E序由实例化一个MyClasscȝ对象开始,该对象有三个实例变量Q类型分别ؓString、int、doubleQ是希望存储和恢复的信息。[/b:a55efb5f91]
[code:1:a55efb5f91]
import java.io.*;
public class SerializationDemo{
public static void main(String args[]){
//Object serialization
try{
MyClass object1=new MyClass("Hello",-7,2.7e10);
System.out.println("object1:"+object1);
FileOutputStream fos=new FileOutputStream("serial");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(object1);
oos.flush();
oos.close();
}
catch(Exception e){
System.out.println("Exception during serialization:"+e);
System.exit(0);
}
//Object deserialization
try{
MyClass object2;
FileInputStream fis=new FileInputStream("serial");
ObjectInputStream ois=new ObjectInputStream(fis);
object2=(MyClass)ois.readObject();
ois.close();
System.out.println("object2:"+object2);
}
catch(Exception e){
System.out.println("Exception during deserialization:"+e);
System.exit(0);
}
}
}
class MyClass implements Serializable{
String s;
int i;
double d;
public MyClass(String s,int i,double d){
this.s=s;
this.i=i;
this.d=d;
}
public String toString(){
return "s="+s+";i="+i+";d="+d;
}
}
[/code:1:a55efb5f91]
E序q行l果Qobject1和object2的实例变量是一LQ输出如下:[code:1:a55efb5f91]object1:s=Hello;i=-7;d=2.7E10
object2:s=Hello;i=-7;d=2.7E10[/code:1:a55efb5f91]
<!--========================================================-->
hehe
未必是RMI?br />
持久化也是Serializable的重?..
<!--========================================================-->
//agree
持久化是Serializable开始的目的?br />
g有什么心得,是不是也response一下?
<!--========================================================-->
现在知道是怎么回事?----Thank Bruce Eckel a million times for his excellent <<Think in java(Second Edition) >>.书里面讲的好清楚啊?br />
一。猫写的不大全Q可能是因ؓ我的帖子里写?#8220;一般在什么情况下?#8221;q话作怪?br />
我补充一下:
Object serialization的定义:
Object serialization 允许你将实现了Serializable接口的对象{换ؓ字节序列Q这些字节序列可以被完全存储以备以后重新生成原来的对象?
serialization不但可以在本机做Q而且可以l由|络操作Q就是猫说的RMIQ。这个好处是很大?---因ؓ它自动屏蔽了操作pȝ的差异,字节序Q用Unix下的c开发过|络~程的h应该知道q个概念Q我容易在q上面犯错){。比如,在Windowq_生成一个对象ƈ序列化之Q然后通过|络传到一台Unix机器上,然后可以在这台Unix机器上正地重构q个对象?/p>
Object serialization主要用来支持2U主要的Ҏ:
1。Java的RMI(remote method invocation).RMI允许象在本机上一h作远E机器上的对象。当发送消息给q程对象Ӟ需要用到serializaiton机制来发送参数和接收q回直?/p>
2。Java的JavaBeans. Bean的状态信息通常是在设计旉|的。Bean的状态信息必被存v来,以便当程序运行时能恢复这些状态信息。这也需要serializaiton机制?/p>
二。sakulagi和rollingpig说的持久化我也说一下?br /> 我觉得你们说的应该是英文里的persistence.但是Java语言里现在只支持lightweight persistence,是轻量U持久化Q这是通过serialization机制来实现的?/p>
persistence是指一个对象的生命周期不由E序是否执行来决定,即是在E序l止时这个对象也存在。它把一个serializable的对象写到磁盘(本机或其他机器上的非RAM存储器)Qƈ在程序重新调用时再读取对象到通常的RAM存储器?/p>
Z么说Java的serialization机制实现的是lightweight persistence?因ؓ你必L式的序列化和反序列化E序里的对象Q而不是直接由一个关键词来定义一个对象是序列化的然后ql做相应的处理?nbsp; 如果以后的Java版本出现一个新的关键字来实现这U机Ӟ比如是persistence,如果我用
persistence (String s="chinaunix")
然后pȝ自动做猫程序里的那些处理,那么Java实Cpersistence.
W一ơ写q么多,而且是刚看了书不久写的,错误和行文不当之处多包涵?/p>
再次感谢猫小,sakulagi和rollingpigl的提示?br />
<!--========================================================-->
Joshua Bloch ?"Effective Java Programming Language Guide" 里面关于 Serializable 的部分讲得也很好Q尤其是什么时候该用,什么时候不该用?br />
<!--========================================================-->
关于序列化处理Bean的状态信息能不能说的详细具体一些呢Q谢谢!
<!--========================================================-->
q儿我没有写q,我想是通过序列化beanQ进行writeObjectҎ可以数据写入数据库的一个表?br />
oracle对这Ҏ支持?
SimpleDateFormat 允许以ؓ日期-旉格式化选择M用户指定的方式启动?但是Q希望用 DateFormat 中的 getTimeInstance?getDateInstance ?getDateTimeInstance 创徏一个日?旉格式化程序?每个cL法返回一个以~省格式化方式初始化的日期/旉格式化程序?可以Ҏ需要用 applyPattern Ҏ修改格式化方式?
SimpleDateFormat函数的承关p:
java.lang.Object
|
+----java.text.Format
|
+----java.text.DateFormat
|
+----java.text.SimpleDateFormat
下面是个例子:
import java.text.*;
import java.util.Date;
/**
SimpleDateFormat函数语法Q?br />
G q代标志W?br />
y q?br />
M ?br />
d ?br />
h ?在上午或下午 (1~12)
H ?在一天中 (0~23)
m ?br />
s U?br />
S 毫秒
E 星期
D 一q中的第几天
F 一月中W几个星期几
w 一q中W几个星?br />
W 一月中W几个星?br />
a 上午 / 下午 标记W?
k ?在一天中 (1~24)
K ?在上午或下午 (0~11)
z 时区
*/
public class FormatDateTime {
public static void main(String[] args) {
SimpleDateFormat myFmt=new SimpleDateFormat("yyyyqMM月dd?HH时mm分ssU?);
SimpleDateFormat myFmt1=new SimpleDateFormat("yy/MM/dd HH:mm");
SimpleDateFormat myFmt2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//{h于now.toLocaleString()
SimpleDateFormat myFmt3=new SimpleDateFormat("yyyyqMM月dd?HH时mm分ssU?E ");
SimpleDateFormat myFmt4=new SimpleDateFormat(
"一q中的第 D ?一q中Ww个星?一月中WW个星?在一天中k?z时区");
Date now=new Date();
System.out.println(myFmt.format(now));
System.out.println(myFmt1.format(now));
System.out.println(myFmt2.format(now));
System.out.println(myFmt3.format(now));
System.out.println(myFmt4.format(now));
System.out.println(now.toGMTString());
System.out.println(now.toLocaleString());
System.out.println(now.toString());
}
}
效果Q?br />
2007q?0?6?17?4?7U?br />
07/10/16 17:24
200-10-16 17:24:27
2007q?0?6?17?4?7U?星期?
一q中的第 351 ?一q中W?1个星?一月中W?个星?在一天中17?CST时区
16 Dec 2007 09:24:27 GMT
2007-10-16 17:24:27
Thu Dec 16 17:24:27 CST 200
下面是个JavaBean:
public class FormatDateTime {
public static String toLongDateString(Date dt){
SimpleDateFormat myFmt=new SimpleDateFormat("yyyyqMM月dd?HH时mm分ssU?E ");
return myFmt.format(dt);
}
public static String toShortDateString(Date dt){
SimpleDateFormat myFmt=new SimpleDateFormat("yyqMM月dd?HH时mm?);
return myFmt.format(dt);
}
public static String toLongTimeString(Date dt){
SimpleDateFormat myFmt=new SimpleDateFormat("HH mm ss SSSS");
return myFmt.format(dt);
}
public static String toShortTimeString(Date dt){
SimpleDateFormat myFmt=new SimpleDateFormat("yy/MM/dd HH:mm");
return myFmt.format(dt);
}
public static void main(String[] args) {
Date now=new Date();
System.out.println(FormatDateTime.toLongDateString(now));
System.out.println(FormatDateTime.toShortDateString(now));
System.out.println(FormatDateTime.toLongTimeString(now));
System.out.println(FormatDateTime.toShortTimeString(now));
}
}
调用的main 试l果Q?br />
2007q?2?6?17?8?6U?星期?
07q?2?6?17?8?br />
17 38 26 0965
07/12/16 17:38
==操作W专门用来比较变量的值是否相{。比较好理解的一ҎQ?
int a=10;
int b=10;
则a==b是true?
但不好理解的地方是:
String a=new String("foo");
String b=new String("foo");
则a==b返回false?
对象变量其实是一个引用,它们的值是指向对象所在的内存地址Q而不是对象本w。a和b都用了new操作W,意味着在内存中生两个内容ؓ"foo"的字W串Q既然是“两个”Q它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的|所以?=="操作W,l果会是false。诚Ӟa和b所指的对象Q它们的内容都是"foo"Q应该是“相等”Q但?=操作Wƈ不涉及到对象内容的比较?
对象内容的比较,正是equalsҎ做的事?
看一下Object对象的equalsҎ是如何实现的Q?
boolean equals(Object o){
return this==o;
}
Object对象默认使用?=操作W。所以如果你自创的类没有覆盖equalsҎQ那你的cM用equals和?=会得到同Ll果。同样也可以看出QObject的equalsҎ没有辑ֈequalsҎ应该辑ֈ的目标:比较两个对象内容是否相等。因为答案应该由cȝ创徏者决定,所以Object把这个Q务留l了cȝ创徏者?
看一下一个极端的c:
Class Monster{
private String content;
...
boolean equals(Object another){ return true;}
}
我覆盖了equalsҎ。这个实CD无论Monster实例内容如何Q它们之间的比较永远q回true?
所以当你是用equalsҎ判断对象的内Ҏ否相{,请不要想当然。因为可能你认ؓ相等Q而这个类的作者不q样认ؓQ而类的equalsҎ的实现是׃掌握的。如果你需要用equalsҎQ或者用Q何基于散列码的集合(HashSet,HashMap,HashTableQ,请察看一下java doc以确认这个类的equals逻辑是如何实现的?