算法比较简单,没有采用递归,javascript实现如下,可以轻易转为其他语言 var stack = new Array();
var scanned = false;
var temp = root;
while (temp) {
stack.push(temp);
if(!scanned&&temp.firstChild){
temp = temp.firstChild;
continue;
}
if(temp.nextSibling){
temp = temp.nextSibling;
scanned = false;
continue;
}
scanned = true;
temp = temp.parentNode;
}
posted @
2012-07-18 21:34 zhanghu198901 阅读(724) |
评论 (0) |
编辑 收藏
spring 的三种注入方式
1. 接口注入( 不推荐 )
2. getter , setter 方式注入( 比较常用 )
3. 构造器注入( 死的应用 )
关于 getter 和 setter 方式的注入
· autowire="defualt"
· autowire=“byName”
· autowire="bytype"
详细解析注入方式
例如:有如下两个类需要注入
第一个类:
- package org.jia;
-
- public class Order {
- private String orderNum;
- @SuppressWarnings ( "unused" )
- private OrderItem orderitem;
-
- public OrderItem getOrderitem() {
- return orderitem;
- }
-
- public void setOrderitem(OrderItem orderitem) {
- this .orderitem = orderitem;
- }
-
- public String getOrderNum() {
- return orderNum;
- }
-
- public void setOrderNum(String orderNum) {
- this .orderNum = orderNum;
- }
- }
第二个类:
- package org.jia;
-
- public class OrderItem {
- private String orderdec;
-
- public String getOrderdec() {
- return orderdec;
- }
-
- public void setOrderdec(String orderdec) {
- this .orderdec = orderdec;
- }
- }
常用getter&&setter方式介绍
方式第一种注入:
- <? xml version = "1.0" encoding = "UTF-8" ?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
-
- < beans >
- < bean id = "orderItem" class = "org.jia.OrderItem" >
- < property name = "orderdec" value = "item00001" > </ property >
- </ bean >
- < bean id = "order" class = "org.jia.Order" >
- <!-----注入变量 名字必须与类中的名字一样------->
- < property name = "orderNum" value = "order000007" > </ property >
- < !--注入对象 名字为orderitem,所属的类的应用id为orderItem-- >
- < property name = "orderitem" ref = "orderItem" > </ property >
-
- --> </ bean >
- </ beans >
方式第二种注入: byName
- <? xml version = "1.0" encoding = "UTF-8" ?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- < beans >
- <!--此时的id就必须与Order.java中所定义的OrderItem的对象名称一样了,不然就会找不到-->
- < bean id = "orderitem" class = "org.jia.OrderItem" >
- < property name = "orderdec" value = "item00001" > </ property >
- </ bean >
- < bean id = "order" class = "org.jia.Order" < span style = "color: #ff0000;" > autowire = "byName" </ span > >
- < property name = "orderNum" value = "order000007" > </ property >
- </ bean >
- </ beans >
方式第三种注入: byType
- <? xml version = "1.0" encoding = "UTF-8" ?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- < beans >
- <!--按照byType注入则就与id没有关系,可以随便定义id !!!但是不能出现多个此类的id-->
- < bean id = "orderitdfadafaem" class = "org.jia.OrderItem" >
- < property name = "orderdec" value = "item00001" > </ property >
- </ bean >
- < bean id = "order" class = "org.jia.Order" < span style = "color: #ff0000;" > autowire = "byType" </ span > >
- < property name = "orderNum" value = "order000007" > </ property >
- </ bean >
- </ beans >
autowire="constructor"
需要在 Order.java 中加入一个构造器
- public Order(OrderItem item )
- {
- orderitem = item;
- }
XML配置文件
- <? xml version = "1.0" encoding = "UTF-8" ?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- < beans >
- < bean id = "orderItem" class = "org.jia.OrderItem" >
- < property name = "orderdec" value = "item00001" > </ property >
- </ bean >
- < bean id = "order" class = "org.jia.Order" autowire = "constructor" >
- < property name = "orderNum" value = "order000007" > </ property >
- </ bean >
- </ beans >
三种注入方式比较
接口注入:
接口注入模式因为具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有限。
Setter 注入:对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。
如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。
如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。
构造器注入:在构造期间完成一个完整的、合法的对象。
所有依赖关系在构造函数中集中呈现。
依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。
只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。
总结
Spring使用注入方式,为什么使用注入方式,这系列问题实际归结起来就是一句话,Spring的注入和
IoC (本人关于IoC的阐述)反转控制是一回事。
理论上:第三种注入方式(构造函数注入)在符合java使用原则上更加合理,第二种注入方式(setter注入)作为补充。
posted @
2012-07-18 21:33 zhanghu198901 阅读(1326) |
评论 (0) |
编辑 收藏
统一目录下的资源结构图:
<html>
<head>
<link rel="stylesheet" href="gallery.css" type="text/css" media="screen" charset="utf-8"/>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="container">
<div id="header">
<h1>StarTrackr!</h1>
</div>
<div id="content">
<h2>Around Town Last Night</h2>
<div id="ajaxInProgress"></div>
<div id="photos">
<fieldset id="photoDetails">
<legend>Photo Tagging</legend>
<form id="details">
<p id="status"></p>
<p>
<label for="name">Name:</label><br/>
<input type="text" class="textField" name="name" id="name" />
</p>
<p>
<label for="tags">Tags:</label><br/>
<input type="text" class="textField" name="tags" id="tags" />
</p>
<p>
<input type="hidden" name="id" id="id">
<input type="button" value="update" id="update" />
</p>
</form>
<div id="gallery"></div>
</fieldset>
</div>
</div>
</div>
</body>
</html>
posted @
2012-07-18 21:32 zhanghu198901 阅读(872) |
评论 (0) |
编辑 收藏
只有在学会处理异常之后,我们才能说自己是一个合格的java程序员。只有在摆脱了以下六种异常处理的陋习之后,才能威慑一下刚毕业的小菜鸟。
现在就来测试一下大家对异常的掌握程度。不用担心,事实上,这些不合理的设计很容易看出来。那么,以下六种不合理的代码,大家能看出每一种的问题出在哪儿吗?
OutputStreamWriter out = ...
java.sql.Connection conn = ...
try { // ⑸
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery(
"select uid, name from user");
while (rs.next())
{
out.println("ID:" + rs.getString("uid") // ⑹
+ ",姓名:" + rs.getString("name"));
}
conn.close(); // ⑶
out.close();
}
catch(Exception ex) // ⑵
{
ex.printStackTrace(); //⑴,⑷
}
作为一个Java程序员,你至少应该能够找出两个问题。但是,如果你不能找出全部六个问题,请继续阅读本文。
本文讨论的不是Java异常处理的一般性原则,因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为“反例”(anti-pattern)的违背优秀编码规范的常见坏习惯,帮助读者熟悉这些典型的反面例子,从而能够在实际工作中敏锐地察觉和避免这些问题。
反例之一:丢弃异常
代码:15行-18行。
这段代码捕获了异常却不作任何处理,可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看,它也许可以和C/C++程序的一个恶名远播的问题相提并论??不检查缓冲区是否已满。如果你看到了这种丢弃(而不是抛出)异常的情况,可以百分之九十九地肯定代码存在问题(在极少数情况下,这段代码有存在的理由,但最好加上完整的注释,以免引起别人误解)。
这段代码的错误在于,异常(几乎)总是意味着某些事情不对劲了,或者说至少发生了某些不寻常的事情,我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上“处理异常”。不错,调用printStackTrace对调试程序有帮助,但程序调试阶段结束之后,printStackTrace就不应再在异常处理模块中担负主要责任了。
丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档,可以看到下面这段说明:“特别地,虽然出现ThreadDeath是一种‘正常的情形’,但ThreadDeath类是Error而不是Exception的子类,因为许多应用会捕获所有的Exception然后丢弃它不再理睬。”这段话的意思是,虽然ThreadDeath代表的是一种普通的问题,但鉴于许多应用会试图捕获所有异常然后不予以适当的处理,所以JDK把 ThreadDeath定义成了Error的子类,因为Error类代表的是一般的应用不应该去捕获的严重问题。可见,丢弃异常这一坏习惯是如此常见,它甚至已经影响到了Java本身的设计。
那么,应该怎样改正呢?主要有四个选择:
1、处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经“处理好了异常”。
2、重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。
3、把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)。
4、不要捕获异常。
结论一:既然捕获了异常,就要对它进行适当的处理。不要捕获异常之后又把它丢弃,不予理睬。
反例之二:不指定具体的异常
代码:15行。
许多时候人们会被这样一种“美妙的”想法吸引:用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exceptionex)语句。但实际上,在绝大多数情况下,这种做法不值得提倡。为什么呢?
要理解其原因,我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生,catch(Exceptionex)就相当于说我们想要处理几乎所有的异常。
再来看看前面的代码例子。我们真正想要捕获的异常是什么呢?最明显的一个是SQLException,这是JDBC操作中常见的异常。另一个可能的异常是IOException,因为它要操作OutputStreamWriter.显然,在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说,catch语句应当尽量指定具体的异常类型,而不应该指定涵盖范围太广的Exception类。
另一方面,除了这两个特定的异常,还有其他许多异常也可能出现。例如,如果由于某种原因,executeQuery返回了null,该怎么办?答案是让它们继续抛出,即不必捕获也不必处理。实际上,我们不能也不应该去捕获可能出现的所有异常,程序的其他地方还有捕获异常的机会??直至最后由 JVM处理。
结论二:在catch语句中尽可能指定具体的异常类型,必要时使用多个catch.不要试图处理所有可能出现的异常。
反例之三:占用资源不释放
代码:3行-14行。
异常改变了程序正常的执行流程。这个道理虽然简单,却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源,即使遇到了异常,也要正确释放占用的资源。为此,Java提供了一个简化这类操作的关键词finally.
finally是样好东西:不管是否出现了异常,Finally保证在try/catch/finally块结束之前,执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally.
当然,编写finally块应当多加小心,特别是要注意在finally块之内抛出的异常??这是执行清理任务的最后机会,尽量不要再有难以处理的错误。
结论三:保证所有资源都被正确释放。充分运用finally关键词。
反例之四:不说明异常的详细信息
代码:3行-18行。
仔细观察这段代码:如果循环内部出现了异常,会发生什么事情?我们可以得到足够的信息判断循环内部出错的原因吗?不能。我们只能知道当前正在处理的类发生了某种错误,但却不能获得任何信息判断导致当前错误的原因。
printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程,但只提供了一些最基本的信息,未能说明实际导致错误的原因,同时也不易解读。
因此,在出现异常时,最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。
结论四:在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。
反例之五:过于庞大的try块
代码:3行-14行。
经常可以看到有人把大量的代码放入单个try块,实际上这不是好习惯。这种现象之所以常见,原因就在于有些人图省事,不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子,虽然东西是带上了,但要找出来可不容易。
一些新手常常把大量的代码放入单个try块,然后再在catch语句中声明Exception,而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难,因为一大段代码中有太多的地方可能抛出Exception.
结论五:尽量减小try块的体积。
反例之六:输出数据不完整
代码:7行-11行。
不完整的数据是Java程序的隐形杀手。仔细观察这段代码,考虑一下如果循环的中间抛出了异常,会发生什么事情。循环的执行当然是要被打断的,其次,catch块会执行??就这些,再也没有其他动作了。已经输出的数据怎么办?使用这些数据的人或设备将收到一份不完整的(因而也是错误的)数据,却得不到任何有关这份数据是否完整的提示。对于有些系统来说,数据不完整可能比系统停止运行带来更大的损失。
较为理想的处置办法是向输出设备写一些信息,声明数据的不完整性;另一种可能有效的办法是,先缓冲要输出的数据,准备好全部数据之后再一次性输出。
结论六:全面考虑可能出现的异常以及这些异常对执行流程的影响。
改写后的代码
根据上面的讨论,下面给出改写后的代码。也许有人会说它稍微有点?嗦,但是它有了比较完备的异常处理机制。
OutputStreamWriter out = ...
java.sql.Connection conn = ...
try {
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery(
"select uid, name from user");
while (rs.next())
{
out.println("ID:" + rs.getString("uid") + ",姓名: " + rs.getString("name"));
}
}
catch(SQLException sqlex)
{
out.println("警告:数据不完整");
throw new ApplicationException("读取数据时出现SQL错误", sqlex);
}
catch(IOException ioex)
{
throw new ApplicationException("写入数据时出现IO错误", ioex);
}
finally
{
if (conn != null) {
try {
conn.close();
}
catch(SQLException sqlex2)
{
System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString());
}
}
if (out != null) {
try {
out.close();
}
catch(IOException ioex2)
{
System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString());
}
}
}
本文的结论不是放之四海皆准的教条,有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心,务必加上详细、全面的注释。
另一方面,不要笑话这些错误,不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途,原因很简单,因为它们确确实实带来了“方便”。所有这些反例都可以看作Java编程世界的恶魔,它们美丽动人,无孔不入,时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事,不足挂齿,但请记住:勿以恶小而为之,勿以善小而不为。
posted @
2012-07-16 22:20 zhanghu198901 阅读(1759) |
评论 (1) |
编辑 收藏
单表继承映射
每棵类继承树使用一个表。
映射文件Extends.hbm.xml。
<hibernate-mapping package="com.snail.hibernate">
<class name="Animal" table="t_animal" lazy="false">
<id name="id">
<generator class="native"/>
</id>
<discriminator column="type" type="string"/>
<property name="name"/>
<property name="sex"/>
<subclass name="Pig" discriminator-value="P">
<property name="weight"/>
</subclass>
<subclass name="Brid" discriminator-value="B">
<property name="height"/>
</subclass>
</class>
</hibernate-mapping>
因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:
(一)父类用普通的<class>标签定义
(二)在父类中定义一个discriminator,即指定这个区分的字段的名称和类型
如:<discriminator column=”XXX” type=”string”/>
(三)子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:
1.Subclass标签的name属性是子类的全路径名;
2.在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)的值;
3.Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值是父类的全路径名称。
4.子类的其它属性,像普通类一样,定义在subclass标签的内部。
具体表继承映射
每个具体类一张表。(同上例)
映射文件Extends.hbm.xml。
<hibernate-mapping package="com.snail.hibernate">
<class name="Animal" table="t_animal" lazy="false" abstract="true">
<id name="id">
<generator class="assigned"/>
</id>
<property name="name"/>
<property name="sex"/>
<union-subclass name="Pig" table="t_pig">
<property name="weight"/>
</union-subclass>
<union-subclass name="Brid" table="t_brid">
<property name="height"/>
</union-subclass>
</class>
</hibernate-mapping>
这种策略是使用union-subclass标签来定义子类的。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段(这就是它跟joined-subclass的不同之处,joined-subclass定义的子类的表,只包含子类特有属性映射的字段)。实现这种策略的时候,有如下步骤:
(一)父类用普通<class>标签定义即可;
(二)子类用<union-subclass>标签定义,在定义union-subclass的时候,需要注意如下几点:
1.Union-subclass标签不再需要包含key标签(与joined-subclass不同)。
2.Union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当Union-subclass标签的定义与class标签平行的时候,需要在Union-subclass标签中,添加extends属性,里面的值是父类的全路径名称。
3.子类的其它属性,像普通类一样,定义在Union-subclass标签的内部。这个时候,虽然在union-subclass里面定义的只有子类的属性,但是因为它继承了父类,所以,不需要定义其它的属性,在映射到数据库表的时候,依然包含了父类的所有属性的映射字段。
注意:在保存对象的时候id不能重复(不能使用数据库的自增方式生成主键)
类表继承映射
每个类一张表。(同上例)
映射文件Extends.hbm.xml。
- <hibernate-mapping package="com.snail.hibernate">
- <class name="Animal" table="t_animal" lazy="false">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- <property name="sex"/>
- <joined-subclass name="Pig" table="t_pig">
- <key column="pid"/>
- <property name="weight"/>
- </joined-subclass>
- <joined-subclass name="Brid" table="t_brid">
- <key column="bid"/>
- <property name="height"/>
- </joined-subclass>
- </class>
- </hibernate-mapping>
这种策略是使用joined-subclass标签来定义子类的。父类、子类,每个类都对应一张数据库表。在父类对应的数据库表中,实际上会存储所有的记录,包括父类和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字段。子类与父类,通过相同的主键值来关联。实现这种策略的时候,有如下步骤:
(一)父类用普通的<class>标签定义即可,父类不再需要定义discriminator字段;
(二)子类用<joined-subclass>标签定义,在定义joined-subclass的时候,需要注意如下几点:
1.Joined-subclass标签的name属性是子类的全路径名
2.Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。
如:<key column=”PARENT_KEY_ID”/>,这里的column,实际上就是父类的主键对应的映射字段名称。
3.Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当Joined-subclass标签的定义与class标签平行的时候,需要在Joined-subclass标签中,添加extends属性,里面的值是父类的全路径名称。
4.子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。
posted @
2012-07-16 22:16 zhanghu198901 阅读(997) |
评论 (0) |
编辑 收藏
function MillisecondToDate(msd) {
var time = parseFloat(msd) /1000;
if (null!= time &&""!= time) {
if (time >60&& time <60*60) {
time = parseInt(time /60.0) +"分钟"+ parseInt((parseFloat(time /60.0) -
parseInt(time /60.0)) *60) +"秒";
}else if (time >=60*60&& time <60*60*24) {
time = parseInt(time /3600.0) +"小时"+ parseInt((parseFloat(time /3600.0) -
parseInt(time /3600.0)) *60) +"分钟"+
parseInt((parseFloat((parseFloat(time /3600.0) - parseInt(time /3600.0)) *60) -
parseInt((parseFloat(time /3600.0) - parseInt(time /3600.0)) *60)) *60) +"秒";
}else {
time = parseInt(time) +"秒";
}
}else{
time = "0 时 0 分0 秒";
}
return time;
}
posted @
2012-07-12 22:30 zhanghu198901 阅读(2745) |
评论 (1) |
编辑 收藏
1、windows->Preferences...打开"首选项"对话框,左侧导航树,导航到general->Workspace,右侧Text file encoding,选择Other,改变为 utf-8(必须小写),以后新建立工程其属性对话框中的Text file encoding即为UTF-8。
2、windows->Preferences...打开"首选项"对话框,左侧导航树,导航到general->Content Types,右侧Content Types树,点开Text,选择 Java Source File,在下面的Default encoding输入框中输入UTF-8,点Update,则设置Java文件编码为UTF-8。然后设置jsp、js、css等类型的Default encoding,设置方式同Java Source File。
3.windows->Preferences...打开"首选项"对话框,左侧导航树,导航到MyEclipse->Files and Editors->JSP,把Encoding改为UTF-8
posted @
2012-07-12 22:30 zhanghu198901 阅读(6142) |
评论 (0) |
编辑 收藏
1、java.lang包下的80%以上的类的功能的灵活运用。
2、java.util包下的80%以上的类的灵活运用,特别是集合类体系、正规表达式、时间、属性、和Timer.
3、java.io包下的60%以上的类的使用,理解IO体系的基于管道模型的设计思路以及常用IO类的特性和使用场合。
4、java.math包下的100%的内容。
5、java.net包下的60%以上的内容,对各个类的功能比较熟悉。
6、java.text包下的60%以上的内容,特别是各种格式化类。
7、熟练运用JDBC.
8、java.security包下40%以上的内容,如果对于安全没有接触的话根本就不可能掌握java.
9、AWT的基本内容,包括各种组件事件、监听器、布局管理器、常用组件、打印。
10、Swing的基本内容,和AWT的要求类似。
11、XML处理,熟悉SAX、DOM以及JDOM的优缺点并且能够使用其中的一种完成XML的解析及内容处理。
posted @
2012-07-12 22:30 zhanghu198901 阅读(1107) |
评论 (2) |
编辑 收藏
where 1=1最近看到很多sql里用到where 1=1,原来觉得这没用嘛,但是又想到如果没用为什么要写呢?于是在网上查了查,在这里就浅谈一下:1=1 永真, 1<>1 永假。1<>1 的用处:用于只取结构不取数据的场合例如:create table table_temp tablespace tbs_temp asselect * from table_ori where 1<>1 建成一个与table_ori 结构相同的表table_temp,但是不要table_ori 里的数据。(除了表结构,其它结构也同理)1=1的用处用于动态SQL例如 lv_string := 'select tbl_name,tbl_desc from tbl_test where 1=1 '||l_condition;当用户选择了查询的名称'abc'时l_condition :='and tbl_name = ''abc'''';但是当用户没有选择名称查询时l_condition就为空 这样 lv_string = 'select tbl_name,tbl_desc from tbl_test where 1=1 ' ,运行也不会出错,相当于没有限制名称条件。但是如果没有1=1的条件,则lv_string = 'select tbl_name,tbl_desc from tbl_test where ';这样就会报错。除了1=1 或1<>1之外的其它永真永假的条件同理。
posted @
2012-07-12 22:29 zhanghu198901 阅读(960) |
评论 (0) |
编辑 收藏
在JDK1.2以前的版本中,当一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及状态,程序才能使用它。这 就像在日常生活中,从商店购买了某样物品后,如果有用,就一直保留它,否则就把它扔到垃圾箱,由清洁工人收走。一般说来,如果物品已经被扔到垃圾箱,想再 把它捡回来使用就不可能了。
但有时候情况并不这么简单,你可能会遇到类似鸡肋一样的物品,食之无味,弃之可惜。这种物品现在已经无用了,保留它会占空间,但是立刻扔掉它也不划算,因 为也许将来还会派用场。对于这样的可有可无的物品,一种折衷的处理办法是:如果家里空间足够,就先把它保留在家里,如果家里空间不够,即使把家里所有的垃 圾清除,还是无法容纳那些必不可少的生活用品,那么再扔掉这些可有可无的物品。从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。
1.强引用
本章前文介绍的引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
2.软引用(SoftReference)
如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
3.弱引用(WeakReference)
如果一个对象只具有弱引用,那就类似于可有可物的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它 所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。 弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
4.虚引用(PhantomReference)
"虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃 圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是 否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。
posted @
2012-07-12 22:28 zhanghu198901 阅读(811) |
评论 (0) |
编辑 收藏