星期四, 九月 30, 2004
FireFox中的XML和XSLT的使用及SOAP的引用..
这里有几篇文章非常不错.关于在FireFox中的确XML/XSLT的引用.
Updating DHTML Web Pages for next generation browsers
SOAP in Netscape Gecko-based Browsers
Accessing Web Services In Netscape 7.1/Mozilla 1.4 Using WSDL Proxying
Groovy 1.0 beta 7增加了embed 使用的jar库
Today 2004.9.30.groovy 1 beta 7发表
不过看了看change log.文档没有加入,修改的几个BUG.我都没碰到.
有关ClassLoader的问题,也没有修改.
只是一个小小的版本改动.
星期三, 九月 29, 2004
利用XMLHttpRequest对象来提交数据.
When using XMLHttpRequest object, there is a way to post data in the same way that an HTML Form is posted.
All you need to do is add an HTTP header, and send the data the same way you'd send it on the QueryString.
Here's a JScript example for the client side, that submits form data to another page:
var objHTTP, strResult;
objHTTP = new ActiveXObject('Microsoft.XMLHTTP');
objHTTP.Open('POST',"OtherPage.asp",false);
objHTTP.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
objHTTP.send("id=1&user="+txtUser.value+"&password="+txtPassword.value);
strResult=objHTTP.responseText;
星期一, 九月 27, 2004
欢迎你来到异次元空间!
自爱因斯坦之后,我们关于时空的最奇幻的构思.
我们处在一个最多11维的时空中.
自1995 Nova发表 Welcome to the 11th Dimension论文以来的进展有多少呢?实验室数据如何设计来证明这个理论呢?
有趣的思考.
图片来自:http://groups.msn.com/Realms-Of-Light/thedivinehologramofspirit.msnw
Nova The Elegant Universe: Welcome to the 11th Dimension "The Elegant Universe: Welcome to the 11th Dimension," shows how in 1995 Edward Witten of Princeton's Institute for Advanced Study, aided by others, revolutionized string theory by successfully uniting the five different versions into a single theory that is cryptically named "M-theory," a development which required a total of eleven dimensions. Ten...eleven...who's counting? But the new eleventh dimension is different from all the others, since it implies that strings can come in higher dimensional shapes called membranes, or " branes" for short. These have truly science-fiction-like qualities, since in principle they can be as large as the universe. A brane can even be a universe -- a parallel universe -- and we may be living on one right now. Branes might also explain why gravity is the weakest force, requiring all the matter in the Earth to produce a measly one g. According to this idea, gravity may be far more potent, but most of its strength is leaking into a parallel universe. Witten has described string theory as "a part of 21st-century physics that fell by chance into the 20th century." In fact, the theory is so far ahead of experimental technique that there is as yet no way to verify whether strings are real or a figment of some very creative imaginations. But scientists at the CERN atom-smasher on the French- Swiss border are working to test of one of the predictions of string theory. Scheduled to run later in this decade, this experiment may take an important step in showing that string theory is not just a crazy idea, but crazy reality. (CC) (D) |
如何让Google机器人搜索自己的网站呢?
http://webdesign.about.com/cs/googleoptimization/
关于SEO(Search Engine Optimized)的话题很久了.
但是我不知道Googlebot关于robots.txt和<meta name="Googlebot" content="index,follow"/>
的优先级别顺序是怎样的?
所以需要测试.不过先把<meta>标志加入网页再说其他了.:)
星期五, 九月 24, 2004
B/S开发的新里程碑(B/S application Milestone)XMLHttpRequest
动态HTML及XML:介绍XMLHttpRequest对象
(翻译:有增删:原文见:TaH Website
随着XML数据和Web服务的部署越来越普遍,你偶尔会觉的如果在HTML表现层不需要刷新页面而直接
得到XML数据来更新中间状态也是非常方便的.要感谢可爱的 XMLHttpRequest对象,可以在后台直接
提交或获得XML 数据,这扩展了Web Client的使用范围.
为了改变接受到的XML 数据并渲染成HTML内容,依赖于客户端DOM读取XML文档节点树组成用户最终
看见的HTML元素
历史和支持
Microsoft首先在IE 5 window版本用ActiveX技术实现了XMLHttpRequest对象.Mozilla 项目的工程
师们实现了兼容的本地版本Mozilla 1.0(及Netscape 7).Apple在Safari 1.2上完成了同样的工作.
包含W3C标准期望的相似的功能,DOM level 3载入及保存规范.同时随着支持XMLHttpRequest对象意味着这已经成为事实的标准.以后W3C的规范最终应该会支持它并且所有的browser都会支持的。
如何建立对象?
建立一个XMLHttpRequest对象要求根据不同的Browser用不同的方式来实例化对象.对Safari和
Mozila系列.简单调用对象的constructor功能就可以完成这个:
var req = new XMLHttpRequest();
对使用ActiveX的对象,通过传递对象名称来建立:
var req = new ActiveXObject("Microsoft.XMLHTTP");
两种构造方法都返回一个抽象对象的引用.它的方法控制所有的操作,同时他的属性从服务器返回的数据
对象方法
XMLHttpRequest对象在所有支持的环境中使用都非常简明,但是非常强大,列表所有的方法和属性
Table 1显示Safari 1.2,Mozilla及IE 5及以后的windows版本.
Table 1. 一般XMLHttpRequest对象方法
方法 | 描述 |
abort() | 停止当前请求 |
getAllResponseHeaders() | 返回一组标题头(标识及其值)字符串 |
getResponseHeader("headerLabel") | 返回指定头标识的字符串值 |
open("method", "URL"[, asyncFlag[, "userName"[, "password"]]]) | 给一个等待状态的请求制定目标URL,方法及其它可选的属性 |
send(content) | 发送请求,另外可以附加提交的字符传或DOM对象数据 |
setRequestHeader("label", "value") | 跟随请求设定指顶的标题标识及其值. |
在Table 1中显示的方法.open()和send()方法可能是你最常用的.
首先open(),用来设置一个将要用的操作场景.两个必须的参数是你将要请求的HTTP方法和连接的目
的URL.对于method参数,你可以设置"GET"接受基本数据.然后使用"POST"发送数据到服务器,尤其是数据可能大于512字节.URL可以是绝对或相对地址(不过可能引起Browser安全问题)
重要的第三个选项参数是Boolean值用来控制是否将来的事物是否异步.默认的行为是true既异步,
这表示脚本进程在调用send()后立即返回不要等待回应.如果你设置这个值为false,那么,脚本将等
到服务器返回数据为止.看起来似乎等待服务器返回数据再继续脚本进程是个好主意.但是这样做可能导致脚本因为网络或服务器问题而不能完成事务,导致脚本挂死.一个安全的主意是用send 异步操作方式,但把代码挂在onreadstatechange事件上是个好主意.
如下例:
var req;
function loadXMLDoc(url) {
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send(null);
// branch for IE/Windows ActiveX version
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send();
}
}
}
注意:从服务器返回的数据必须保证Content-Type是:text/xml 内容设置为text/plain或text/html
不被request对象接受.
对象属性
Table 2. 所有属性都是只读的
Table 2. 常见 XMLHttpRequest对象属性
属性 | 说明 |
onreadystatechange | 当每个状态改变时产生的事件 |
ReadyState | 对象状态整数0 = uninitialized1 = loading2 = loaded3 = interactive4 = complete |
responseText | 服务器返回结果的字符串样本 |
responseXML | DOM规范的服务器返回结果 |
status Numeric | code returned by server, such as 404 for "Not Found" or 200 for "OK" |
statusText | String message accompanying the status code |
如何使用XMLHttpRequest和DIV来动态载入内容
红色的为关键代码。
<div id=content name="content" width=80% heigth=80% >
wait
</div>
<script>
var http;
http = new XMLHttpRequest();
try
{
http.open("GET", "http://wang.journalspace.com", true);
}catch(e)
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
//弹出安全限制对话框,要用户授权。
http.open("GET", "http://wang.journalspace.com", true);
http.onreadystatechange=function() {
if (http.readyState==4) {
alert(http.responseText);
document.getElementById('content').innerHTML=http.responseText;
}
}
document.getElementById('content').innerHTML="Wait...";
http.send('');
}
</script>
Signed Scripts in Mozilla
http://www.mozilla.org/projects/security/components/signed-scripts.html
星期四, 九月 23, 2004
MySql如何增加一个新用户或改密码.
GRANT ALL PRIVILEGES ON *.* TO ehrm@"myhost" IDENTIFIED BY 'xxxxx' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO ehrm@"%" IDENTIFIED BY 'xxxxx' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO ehrm@localhost IDENTIFIED BY 'xxxxx' WITH GRANT OPTION;
FLUSH PRIVILEGES;
利用IE6和Javascript同服务器交互
When using XMLHttpRequest object, there is a way to post data in the same way that an HTML Form is posted.
All you need to do is add an HTTP header, and send the data the same way you'd send it on the QueryString.
Here's a JScript example for the client side, that submits form data to another page:
var objHTTP, strResult;
objHTTP = new ActiveXObject('Microsoft.XMLHTTP');
objHTTP.Open('POST',"OtherPage.asp",false);
objHTTP.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
objHTTP.send("id=1&user="+txtUser.value+"&password="+txtPassword.value);
strResult=objHTTP.responseText;
Javascript 同Regua参考资料
http://developer.netscape.com/viewsource/angus_strings.html
及通过.prototype扩展Javascript的功能.
http://www.javascriptkit.com/javatutors/proto4.shtml
星期三, 九月 22, 2004
如何避免GroovyClassLoader Defect 不足.避免动态类占用内存资源.
GroovyShell _shell=new GroovyShell(new Binding());
String text="tax=0.4; return 1000*tax;";
for(int i=0;i<3000;i++)
{
System.out.println(_shell.evaluate(text,"textScript.groovy"));
}
通过使用GroovyShell.evaluate(String script,String fileName)可以避免同一段脚本,被GroovyShell生成多个动态类保存在cache里.
如何使用JAX-RPC使用Java Object 当做Web Service
详细内容参考http://java.sun.com/developer/EJTechTips/2004/tt0824.html#1
星期二, 九月 21, 2004
如何利用Dynamic ClassLoader 来动态载入Class
import groovy.lang.GroovyShell;
import groovy.lang.Binding;
import groovy.lang.Closure;
import groovy.lang.Script;
import groovy.lang.*;
public class testGroovyMemoryLeak
{
public static void main(String[] args) throws Exception
{
String text="tax=0.4; return 1000*tax;";
ClassLoader parent = Thread.currentThread().getContextClassLoader();
GroovyObject groovyObject=null;
GroovyClassLoader loader=null;
Class groovyClass =null;
Object temp=null;
for(int i=0;i<3000;i++)
{
loader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
groovyClass = loader.parseClass(text);
groovyObject = (GroovyObject) groovyClass.newInstance();
temp = groovyObject.invokeMethod("run", args);
System.out.println("value="+temp);
temp=null;
loader=null;
System.gc();
}
}
}
星期一, 九月 20, 2004
Java Groovy 1.0 beta 6避免GroovyClassloader不能GC Class的问题
不能回收解析脚本动态产生的Scriptxxxx class.
原因是Groovy MetaClass使用了 static HashMap 来cache生成的class.
解决办法,模拟groovy 自己产生一个GroovyObject Arrays.
然后,把动态生成的GroovyObject放入数组,只生成一次,以后直接从数组中载入Class对象实例。
星期日, 九月 19, 2004
TTS Ask:What do you want in Next Java?
1.Better NullPointerException display(臭名远播的NPE问题)
display what name and property get Null
2.Dynamic class
通过申明生成动态类(如果Groovy加入很多问题就解决了)
3.改善ClassLoader behavior
JVM ClassLoader drive me madness.要求清晰简单的行为定义
4.Raw Socket Support
本地Socket支持。哈。这样大多数黑客(Cracker)软件就用Java development了。:)
5.XML/XSLT/XPATH支持.目前的JAXP使用太复杂了。典型的过度设计(over Designed)
6.discard setter 和getter 在Bean上的使用。
目前的沉闷的getter和setter对策略让人发疯。为什么不使用bean.propetyName直接引用呢?
7.Debug 功能要加强
包括#ifdef macro和JVM DUMP及Heap snapshot功能。Third Part module is argly.
What is Next Bigger Feature of Java?
今天看到TSS上也有人赞赏加入Closure在下一个版本中。
自从J2SE 5.0发布后,支持Closure成了一个水到渠成的步骤。
因为AutoBox,AutoUnbox和Generetor泛型的支持已经为
J2SE支持Closure的自然加入了低层支持。
在C# 2中加入了匿名代理的功能,从设计角度来说,提供了基本相识的功能。
其实JVM只要在inner class的基础上加上Autobox和Generetor的提高。
基本上可以提供Closure的功能了。不过很多Closure可以提供的比如data Pine
依然无法提供。
所以最好重新设计Closure替代inner class.
原文:
http://www.theserverside.com/news/thread.tss?thread_id=28808
星期六, 九月 18, 2004
关于Java ClassLoader和Groovy Temporary Class Load and Unload
在Java 中通过GroovyShell或GroovyClassloader来调用存放在数据库中的脚本,Groovy 编译会产生大量的Scriptxxx,xxx表示顺序好的临时class,这些class根据java classloader的规范,就存放在cache中了。
所以一个循环调用Groovy script脚本,会引起内存为了保存这些临时class产生大量的空间。
为了避免ClassLoader对这些class的引用。
需要每次执行脚本时候,必须生成一个新的ClassLoader来调用,然后释放掉。
这样就可以让JVM回收这些空间了。
代码:
星期五, 九月 17, 2004
关于Java GC(Gargabe Collection)回收的机制
The Truth About Garbage Collection
Garbage collection (GC) is probably the most widely misunderstood feature
of the Java platform. GC is typically advertised as removing all memory management
responsibility from the application developer. This just isn't the case. On the
other hand, some developers bend over backwards trying to please the collector,
and often wind up doing much more work than is required. A solid understanding
of the garbage collection model is essential to writing robust, high-performance
software for the Java platform.
This appendix provides an overview of the garbage collection mechanisms that will help you make intelligent choices about memory management issues. It also contains information to help you debug complex problems such as memory leaks.
A.1 Why Should You Care About Garbage Collection?
The cost of allocating and collecting memory can play a significant role in how
your software performs. The overall memory requirements of your software can
have a huge impact on the speed of your program when large RAM requirements
force the OS to use virtual memory. This often occurs when memory is allocated,
but not properly released. Although the JVM is responsible for freeing unused
memory, you have to make it clear what is unused. To write successful, large-scale
programs, you need to understand the basics of the GC mechanism.
A.2 The Guarantees of GC
The specification for the Java platform makes very few promises about how garbage
collection actually works. Here is what the Java Virtual Machine Specification
(JVMS) has to say about memory management.
The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java virtual machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements.1
While it can seem confusing, the fact that the garbage collection model is not rigidly defined is actually important and useful-a rigidly defined garbage collection model might be impossible to implement on all platforms. Similarly, it might preclude useful optimizations and hurt the performance of the platform in the long term.
Although there is no one place that contains a full definition of required garbage collector behavior, much of the GC model is implicitly specified through a number of sections in the Java Language Specification and JVMS. While there are no guarantees about the exact process followed, all compliant virtual machines share the basic object lifecycle described in this chapter.A.3 The Object Lifecycle
In order to discuss garbage collection, it is first useful to examine the object
lifecycle. An object typically goes through most of the following states between
the time it is allocated and the time its resources are finally returned to the system
for reuse.
A.3.1 Created
When an object is created, several things occur:2
- Space is allocated for the object.
- Object construction begins.
- The superclass constructor is called.
- Instance initializers and instance variable initializers are run.
- The rest of constructor body is executed.
The exact costs of these operations depend on the implementation of the JVM, as
well as the implementation of the class being constructed. The thing to keep in
mind is that these costs exist. Once the object has been created, assuming it is
assigned to some variable, it moves directly to the in use state.A.3.2 In Use
Objects that are held by at least one strong reference are considered to be in use.
In JDK 1.1.x, all references are strong references. Java 2 introduces three other
kinds of references: weak, soft and phantom. (These reference types are discussed
in Section A.4.1.) The example shown in Listing A-1 creates an object and assigns
it to some variables.
public class CatTest {
static Vector catList = new Vector();
static void makeCat() {
Object cat = new Cat();
catList.addElement(cat);
}
public static void main(String[] arg) {
makeCat();
// do more stuff
}
}
Creating and referencing an object
Figure A-1 shows the structure of the objects inside the VM just before themakeCat
method returns. At that moment, two strong references point to theCat
object.
Object reference graph
When themakeCat
method returns, the stack frame for that method and any temporary variables it declares are removed. This leaves theCat
object with just a single reference from thecatList
static variable (indirectly via theVector
).A.3.3 Invisible
An object is in the invisible state when there are no longer any strong references
that are accessible to the program, even though there might still be references. Not
all objects go through this state, and it has been a source of confusion for some developers.
Listing A-2 shows a code fragment that creates an invisible object.public void run() {
try {
Object foo = new Object();
foo.doSomething();
} catch (Exception e) {
// whatever
}
while (true) { // do stuff } // loop forever
}
Invisible object
In this example, the objectfoo
falls out of scope when thetry
block finishes. It might seem that thefoo
temporary reference variable would be pulled off the stack at this point and the associated object would become unreachable. After all, once thetry
block finishes, there is no syntax defined that would allow the program to access the object again. However, an efficient implementation of the JVM is unlikely to zero the reference when it goes out of scope. The object referenced byfoo
continues to be strongly referenced, at least until therun
method returns. In this case, that might not happen for a long time. Because invisible objects can't be collected, this is a possible cause of memory leaks. If you run into this situation, you might have to explicitly null your references to enable garbage collection.
A.3.4 Unreachable
An object enters an unreachable state when no more strong references to it exist.
When an object is unreachable, it is a candidate for collection. Note the wording:
Just because an object is a candidate for collection doesn't mean it will be immediately
collected. The JVM is free to delay collection until there is an immediate
need for the memory being consumed by the object.
It's important to note that not just any strong reference will hold an object in memory. These must be references that chain from a garbage collection root. GC roots are a special class of variable that includes
- Temporary variables on the stack (of any thread)
- Static variables (from any class)
- Special references from JNI native code
Circular strong references don't necessarily cause memory leaks. Consider the code in Listing A-3. It creates two objects, and assigns them references to each other.public void buidDog() {
Dog newDog = new Dog();
Tail newTail = new Tail();
newDog.tail = newTail;
newTail.dog = newDog;
}
Circular reference
Figure A-2 shows the reference graph for the objects before thebuildDog
method returns. Before the method returns, there are strong references from the temporary stack variables in thebuildDog
method pointing to both theDog
and theTail
.Reference graph beforebuildDog
returns
Reference graph afterbuildDog
returns
Figure A-3 shows the graph for the objects after thebuildDog
method returns. At this point, theDog
andTail
both become unreachable from a root and are candidates for collection (although the VM might not actually collect these objects for an indefinite amount of time).A.3.5 Collected
An object is in the collected state when the garbage collector has recognized an
object as unreachable and readies it for final processing as a precursor to deallocation.
If the object has afinalize
method, then it is marked for finalization. If it
does not have a finalizer then it moves straight to the finalized state.
If a class defines a finalizer, then any instance of that class must have the finalizer called prior to deallocation. This means that deallocation is delayed by the inclusion of a finalizer.
A.3.6 Finalized
An object is in the finalized state if it is still unreachable after itsfinalize
method, if any, has been run. A finalized object is awaiting deallocation. Note that
the VM implementation controls when the finalizer is run. The only thing that can
be said for certain is that adding a finalizer will extend the lifetime of an object.
This means that adding finalizers to objects that you intend to be short-lived is a
bad idea. You are almost always better off doing your own cleanup instead of relying
on a finalizer. Using a finalizer can also leave behind critical resources that
won't be recovered for an indeterminate amount of time. If you are considering
using a finalizer to ensure that important resources are freed in a timely manner,
you might want to reconsider.
One case where afinalize
method delayed GC was discovered by the quality assurance (QA) team working on Swing. The QA team created a stress testing application that simulated user input by using a thread to send artificial events to the GUI. Running on one version of the toolkit, the application reported anOutOfMemoryError
after just a few minutes of testing. The problem was finally traced back to the fact that the thread sending the events was running at a higher priority than the finalizer thread. The program ran out of memory because about 10,000Graphics
objects were held in the finalizer queue waiting for a chance to run their finalizers. It turned out that theseGraphics
objects were holding onto fairly substantial native resources. The problem was fixed by assuring that whenever Swing is done with aGraphics
object,dispose
is called to ensure that the native resources are freed as soon as possible.
In addition to lengthening object lifetimes, finalize methods can increase object size. For example, some JVMs, such as the classic JVM implementation, add an extra hidden field to objects withfinalize
methods so that they can be held in a linked list finalization queue.A.3.7 Deallocated
The deallocated state is the final step in garbage collection. If an object is still unreachable
after all the above work has occurred, then it is a candidate for deallocation.
Again, when and how deallocation occurs is up to the JVM.A.4 Reference Objects
Prior to the introduction of the Java 2 platform, all references were strong
references. This meant that there was no way for the developer to interact with the
garbage collector, except through brute force methods such asSystem.gc
.
Thejava.lang.ref
package was introduced as part of Java 2. Figure A-4 shows the class hierarchy for the classes in this package. This package defines reference-object classes that enable a limited degree of interaction with the garbage collector.Reference
objects are used to maintain a reference to some other object in such a way that the collector can still reclaim the target object. As you might expect, the addition of these new reference objects complicates the concept of reachability as defined in the object lifecycle. Understanding this is important,
even if you don't intend to make direct use of this package. Some of the core class libraries useWeakReferences
internally, so you might encounter them while using memory profilers to track memory usage.Reference
class hierarchy
A.4.1 Types of Reference Objects
Three types of reference objects are provided, each weaker than the last: soft,
weak, and phantom. Each type corresponds to a different level of reachability:
- Soft references are for implementing memory-sensitive caches.
- Weak references are for implementing mappings that do not prevent their keys
(or values) from being reclaimed.
- Phantom references are for scheduling pre-mortem cleanup actions in a more
flexible way than is possible with the Java finalization mechanism.
Going from strongest to weakest, the different levels of reachability reflect the
lifecycle of an object:
- An object is strongly reachable if some thread can reach it without traversing
any reference objects.
- An object is softly reachable if it is not strongly reachable but can be reached
by traversing a soft reference.
- An object is weakly reachable if it is neither strongly nor softly reachable but
can be reached by traversing a weak reference. When the weak references
to a weakly reachable object are cleared, the object becomes eligible for
finalization.
- An object is phantom reachable if it is neither strongly, softly, nor weakly
reachable, it has been finalized, and some phantom reference refers to it.
- An object is unreachable, and therefore eligible for reclamation, when it is not
reachable in any of the preceding ways.
A.4.2 Example GC with WeakReference
You're likely to encounter special reference objects while using tools to look for
memory leaks. Only strong references will directly interfere with garbage collection.
If you find chains of objects linked by weak references, you should be able to
ignore them from a GC perspective. (For additional information on the use of
special reference objects, see the API documentation.)
Figure A-5 shows a graph of objects in memory for a sample program. Let's say that the problem with this program is that theDog
objects are not being collected, leading to a memory leak. By using a memory profiler, you can find all the pointers to theDog
object and follow them back to their GC roots. There are two GC roots in Figure A-5, a static variable in classKennel
and a stack frame in a live thread. In this case, theWagTask
thread is in an infinite loop, forcing the dog's tail to wag. The question is how to get rid of theDog
object.
There are two references pointing to theDog
object, but only one of them is interesting from a GC perspective. TheWeakReference
from thedogCache
is not important. The interesting reference is the reference from theTail
, which chains from a stack frame in a live thread. To free theDog
, and the associatedTail
, you need to terminate the thread that is wagging theTail
. Once this thread is gone, everything falls into place. When an object that is pointed to by aWeakReference
is collected, theWeakReference
is automatically set tonull.
Figure A-6 shows the result of terminating the wag thread.
Reference graph
When the thread dies, its stack is removed. Now the only strong reference to theDog
is via theTail
, and this becomes a simple circular reference that isn't reachable from a GC root. TheDog
, and by extension theTail
, are no longer strongly reachable through any references. They are only weakly reachable through thedogCache.
When the collector discovers this (which it does on its own schedule), it might set the weak reference tonull,
making theDog
andTail
totally unreachable. They then become candidates for collection and will be removed at the collector's discretion.
Results of garbage collection
A.5 References on Garbage Collection
Arnold, Ken, and James Gosling. The Java Programming Language, Second Edition, Addison-Wesley, Reading, MA, 1998.
Gosling, James, Bill Joy, and Guy Steele. The Java Language Specification, Second Edition, Addison-Wesley, Reading, MA, 2000.
Jones, Richard, and Rafael Lins. Garbage Collection: Algorithms for Automatic Dynamic Memory Management, John Wiley & Sons, New York, 1996.
Lindholm, Tim and Frank Yellin. The Java Virtual Machine Specification, Second Edition, Addison-Wesley, Reading, MA, 1999.
Tim Lindholm and Frank Yellin, The Java Virtual Machine Specification, Second Edition, Section 3.5.3. Addison-Wesley, 1999.
James Gosling, Bill Joy, and Guy Steele, The Java Language Specification, Second Edition. Addison-Wesley, 2000.
God.James的精力也太充沛了吧?
看看他参加了多少开源的项目:
ActiveCluster
ActiveMQ
ActiveSpace
axion
betwixt
commons
db
dom4j
groovy
geronimo
jaxen
jelly
jexl
maven
messenger
panoptes
picocontainer
saxpath
sql
spring
sysunit
taglibs
真是仰慕如黄河之水天上来,滔滔不绝啊.
星期四, 九月 16, 2004
一些Groovy重量级人物的blog及资源
这里有很多关于为什么选择Groovy做为JSR。而不是已经广泛应用的beanshell.或Python或Jruby.
http://justgroovy.org/学习Grooovy的网站.
http://radio.weblogs.com/0112098/2003/08/29.html#a399这是Groovy创建人之一的James的网站。
不过James的个人Email发送无法成功。试图联系不能成功。让人沮丧。
:(.
没办法,Java方面的支持的语言太多了。但从任何细节来说,IO层/数据层/thread.
我觉的Groovy支持的的确是Perfect.
算了,什么时候都要跟着老大Sun走。既然Sun选择了Groovy作为标准JSR。那么我们就学习Groovy了。它的确太伟大了。尤其是Closure(闭包)的概念。简直是天才之笔。
Closure来字数学理论。:)
可以在Google里查询closure.
感受Groovy(介绍伟大的Java Basic :)
介绍 Java 平台的一种新标准语言
CTO, Vanward Technologies
2004 年 8 月
虽然 Java 语言因其严密性和扩展性的承诺而在整整一代程序员中胜出,但是 Groovy 预示了 Java 平台上的一个编程新时代,这种语言是以方便性、适宜性和敏捷性为出发点定义的。在新的 alt.lang.jre 专栏的第二期文章中,Andrew Glover 对提议添加到 Java 平台的标准编程语言作了非正式的介绍。
如果您在使用 Java 平台(block),不管时间长短,您都有可能听说过 Groovy。Groovy 是超级明星开发人员 James Strachan 和 Bob McWhirter 发明的,它是一种敏捷开发语言,完全以 Java 编程 API 为基础。Groovy 当前正处于 Java Specification Request 的开始阶段,它于 2004 年 3 月底获得批准。Groovy 还是一种脚本语言,有些人说它会永久性地改变您看待和使用 Java 平台的方式。
在其对 JSR 241 (请参阅 参考资料)的开放评论中,Groovy 的共同规范领导者 Richard Monson-Haefel 说他对 Groovy 的支持是建立在总有一天 Java 平台要包括一种敏捷开发语言这一信念上。与许多移植到 Java 平台的脚本语言不同,Groovy 是 为 JRE 而写的。在规范请求中(参阅 参考资料),Groovy 的制造者提出了“Java 不仅是一种编程语言,更是一个健壮的平台,可以有多种语言在上面运行和共存”(Monson-Haefel 语)的思想。
新 alt.lang.jre 专栏的这第二期文章的目的是让读者了解 Groovy。我首先回答关于这种新语言的一些最显然的问题(为什么需要它?),然后以代码为基础概述 Groovy 最令人兴奋的功能。
为什么需要另一种语言?
正如在 上个月的专栏 中介绍的,Groovy 不是与 JRE 兼容的惟一脚本语言。Python、Ruby 和 Smalltalk 就是成功地移植到 Java 平台上的三种脚本语言。对于一些开发人员,这带来了问题:为什么要另一种语言?毕竟,我们许多人已经将 Java 代码与 Jython 或者 JRuby 结合来快速开发应用程序,为什么还要学习另一种语言?回答是 您不一定要学习一种新语言以用 Groovy 编码。Groovy 与其他 JRE 兼容脚本语言的不同在于它的语法以及重用 Java 库。Jython 和 JRuby 共享它们前身(分别是 Python 和 Ruby)的外观,Groovy 让人觉得就像是 Java 语言,不过限制要少得多。
像 Jython 这样的语言是在它们的父语言库上建立的,而 Groovy 使用了 Java 开发人员最熟悉的功能和库 ?? 但是将它们放到了一个敏捷开发框架中。敏捷开发的基本宗旨是代码应该很好地适合范围广泛的任务,并可以不同的方式应用。Groovy 通过以下方式落实了这些宗旨:
* 使开发人员不用编译。
* 允许动态类型。
* 使合成结构容易。
* 使其脚本可以在普通 Java 应用程序中使用。
* 提供一个 shell 解析器。
这些特性使 Groovy 成为一种特别容易学习和使用的语言,不管您是有经验的 Java 开发人员还是刚接触 Java 平台。在下面几节中,我将详细讨论上述特性。
看呀,没有 javac!
像许多脚本语言一样,Groovy 不用为运行时编译。这意味着 Groovy 脚本是 在它们运行时 解释的,就像 JavaScript 是在观看 Web 页时由浏览器解释的一样。运行时判断会有执行速度的代价,这有可能使脚本语言不能用于对性能有要求的项目,但是无编译的代码在构建-运行周期中可以提供很多好处。运行时编译使 Groovy 成为快速原型设计、构建不同的实用程序和测试框架的理想平台。
例如,运行脚本 Emailer.groovyin Groovy 就是在命令行键入 groovy Emailer.groovy 这么容易。如果希望运行同样的 Java 文件(Emailer.java),显然必须键入额外的命令:javac Emailer.java,然后是 java Emailer。虽然这看起来可能有些微不足道,但是可以容易设想运行时编译在应用程序开发的更大上下文中的好处。
可以在稍后看到,Groovy 还允许脚本放弃 main 方法以静态地运行一个关联的应用程序。
动态 dynamo
像其他主流脚本语言一样,Groovy 不需要像 C++ 和 Java 语言这样的正式语言的显式类型。在 Groovy 中,一个对象的类型是在运行时动态发现的,这极大地减少了要编写的代码数量。首先可以通过分析清单 1 和 2 中的简单例子看到这一点。
清单 1 显示了在 Java 语言中如何将一个本地变量声明为 String。注意必须声明类型、名和值。
清单 1. Java 静态类型
String myStr = "Hello World";
在清单 2 中,您看到同样的声明,但是不需要声明变量类型。
清单 2. Groovy 动态类型
myStr = "Hello World"
您可能还注意到了,在清单 2 中我可以去掉声明中的分号。在定义方法及其相关的参数时动态类型有戏剧性的后果:多态具有了全新的意义!事实上,使用动态类型,不使用 继承就可以得到多态的全部能力。在清单 3 中,可以真正开始看到动态类型在 Groovy 的灵活性方面所起的作用。
清单 3. 更多 Groovy 动态类型
class Song{
length
name
}
class Book{
name
author
}
def doSomething(thing){
println "going to do something with a thing named = " + thing.name
}
这里,我定义了两个 Groovy 类,Song 和 Book,我将在后面对它们进一步讨论。这两个类都包含一个 name 属性。我还定义了一个函数 doSomething,它以一个 thing 为参数,并试图打印这个对象的 name 属性。
因为 doSomething 函数没有定义其输入参数的类型,只要对象包含一个 name 属性,那么它就可以工作。因此,在清单 4 中,可以看到在使用 Song 和 Book 的实例作为 doSomething 的输入时会有什么现象。
清单 4. 试验动态类型
mySong = new Song(length:90, name:"Burning Down the House")
myBook = new Book(name:"One Duck Stuck", author:"Phyllis Root")
doSomething(mySong) //prints Burning Down the House
doSomething(myBook) //prints One Duck Stuck
anotherSomething = doSomething
anotherSomething(myBook) //prints One Duck Stuck
除了展示 Groovy 中的动态类型,清单 4 的最后两行还揭示了创建对一个函数的引用有多容易。这是因为在 Groovy 中 所有东西 都是对象,包括函数。
关于 Groovy 的动态类型声明最后要注意的是,它会导致更少的 import 语句。尽管 Groovy 需要 import 以显式使用类型,但是这些 import 可以使用别名以提供更短的名字。
动态类型综述
下面两个例子将到目前为止讨论过的 Groovy 中的动态类型的内容放到一起。下面的 Java 代码组和 Groovy 代码组利用了 Freemarker(参阅 参考资料),这是一个开放源代码模板引擎。这两组代码都只是简单地用一个目录和文件名创建一个 Template 对象,然后将相应对象的内容打印到标准输出,当然,不同之处是每一组代码处理这项任务所需要的代码量。
清单 5. 简单的 TemplateReader Java 类
import java.io.File;
import java.io.IOException;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class TemplateReader {
public static void main(String[] args) {
try{
Configuration cfg = Configuration.getDefaultConfiguration();
cfg.setDirectoryForTemplateLoading(
new File("C:\\dev\\projects\\http-tester\\src\\conf"));
Template temp = cfg.getTemplate("vendor-request.tmpl");
System.out.println(temp.toString());
}catch(IOException e){
e.printStackTrace();
}
}
}
初看之下,清单 5 中的 Java 代码相当简单 ?? 特别是如果以前从来没见过脚本代码时。幸运的是,有清单 6 中的 Groovy 作为对比。现在这段代码很简单!
清单 6. 用 Groovy 编写的更简单的 TemplateReader
import freemarker.template.Configuration as tconf
import java.io.File
cfg = tconf.getDefaultConfiguration()
cfg.setDirectoryForTemplateLoading(
new File("C:\\dev\\projects\\http-tester\\src\\conf"))
temp = cfg.getTemplate("vendor-request.tmpl")
println temp.toString()
Groovy 代码只有 Java 代码的一半那么长,下面是原因:
* Groovy 代码只需要一半的 import 语句。还要注意,freemarker.template.Configuration 使用了别名 tconf,使得语法更短。
* Groovy 允许类型为 Template 的变量 tmpl 不声明其类型。
* Groovy 不需要 class 声明或者 main 方法。
* Groovy 不关心任何相应异常,使您可以不用导入 Java 代码中需要的 IOException。
现在,在继续之前,想一下您所编写的最后一个 Java 类。您可能不得不编写很多 import 并声明类型,并在后面加上同样数量的分号。考虑用 Groovy 编写同样的代码会是什么情况。可以使用简练得多的语法,不需要遵守这么多的规则,并且得到完全相同的行为。
想一下,如果您正好是刚刚开始……
特别灵活的语法
谈到语法,灵活性是更有效地开发代码的主要因素。很像其有影响的对手(Python、Ruby 和 Smalltalk),Groovy 极大地简化了核心库的使用和它所模拟的语言(在这里是 Java 语言)的构造。为了让您对 Groovy 语法的灵活性有一个大体概念,我将展示它的一些主要结构,即类、函数(通过 def 关键词)、闭包、集合、范围、映射和迭代器。
类
在字节码水平,Groovy 类是真正的 Java 类。不同之处在于 Groovy 将类中定义的所有内容都默认为 public,除非定义了特定的访问修饰符。而且,动态类型应用到字段和方法,不需要 return 语句。
在清单 7 中可以看到 Groovy 中类定义的例子,其中类 Dog 有一个 getFullName 方法,它实际上返回一个表示 Dog 的全名的 String。并且所有方法都隐式地为 public。
清单 7. 示例 Groovy 类:Dog
class Dog{
name
bark(){
println "RUFF! RUFF!"
}
getFullName(master){
name + " " + master.lname
}
obeyMaster(){
println "I hear you and will not obey."
}
}
在清单 8 中,推广到有两个属性 ?? fname 和 lname ?? 的类 DogOwner ,就是这么简单!
清单 8. 示例 Groovy 类:DogOwner
class DogOwner{
fname
lname
trainPet(pet){
pet.obeyMaster()
}
}
在清单 9 中,用 Groovy 设置属性并对 Dog 和 DogOwner 实例调用方法。现在很明显,使用 Groovy 类比 Java 类要容易得多。虽然需要 new 关键词,但是类型是可选的,且设置属性(它隐式为 public)是相当轻松的。
清单 9. 使用 Groovy 类
myDog = new Dog()
myDog.name = "Mollie"
myDog.bark()
myDog.obeyMaster()
me = new DogOwner()
me.fname = "Ralf"
me.lname = "Waldo"
me.trainPet(myDog)
str = myDog.getFullName(me)
println str // prints Mollie Waldo
注意在 Dog 类中定义的 getFullName 方法返回一个 String 对象,在这里它是 “Mollie Waldo”。
Def
除了像许多脚本语言那样将所有对象指定为第一类对象(见侧栏),Groovy 还让您创建 第一类函数,它本身实质上就是对象。它们是用 def 关键词定义的并在类定义之外。您实际上在 清单 3 中已经看到了如何用 def 关键词定义第一类函数,并在 清单 4 中看到使用了一个函数。Groovy 的第一类函数定义简单脚本时特别有用。
闭包
Groovy 中最令人兴奋和最强大的功能是支持闭包。闭包(Closure) 是第一类对象,它类似于 Java 语言中的匿名内部类。闭包和匿名内部类都是可执行的一段代码,不过这两者之间有一些细微的不同。状态是自动传入传出闭包的。闭包可以有名字。它们可以重复使用。而且,最重要且对 Groovy 同样成立的是,闭包远比匿名内部类要灵活得多!
清单 10 展示了闭包的强大。清单中新的和改进的 Dog 类包括一个 train 方法,它实际上执行创建了 Dog 实例的闭包。
清单 10. 使用闭包
class Dog{
action
train(){
action.call()
}
}
sit = { println "Sit, Sit! Sit! Good dog"}
down = { println "Down! DOWN!" }
myDog = new Dog(action:sit)
myDog.train() // prints Sit, Sit! Sit! Good dog
mollie = new Dog(action:down)
mollie.train() // prints Down! DOWN!
而且,闭包还可以接收参数。如清单 11 所示,postRequest 闭包接收两个参数(location 和 xml),并使用 Jakarta Commons HttpClient 库(参阅 参考资料)将一个 XML 文档发送给指定位置。然后这个闭包返回一个表示响应的 String。闭包定义下面是一个使用闭包的例子。事实上,调用闭包就像调用函数一样。
清单 11. 使用带参数的闭包
import org.apache.commons.httpclient.HttpClient
import org.apache.commons.httpclient.methods.PostMethod
postRequest = { location, xml
clint = new HttpClient()
mthd = new PostMethod(location)
mthd.setRequestBody(xml)
mthd.setRequestContentLength(xml.length())
mthd.setRequestHeader("Content-type",
"text/xml; charset=ISO-8859-1")
statusCode = clint.executeMethod(mthd)
responseBody = mthd.getResponseBody()
mthd.releaseConnection()
return new String(responseBody)
}
loc = "http://localhost:8080/simulator/AcceptServlet/"
vxml = "
str = postRequest(loc, vxml)
println str
集合
将对象组织到像列表和映射这样的数据结构中是一项基本的编码任务,是我们大多数人每天要做的工作。像大多数语言一样,Groovy 定义了一个丰富的库以管理这些类型的集合。如果曾经涉足 Python 或者 Ruby,那么应该熟悉 Groovy 的集合语法。如清单 12 所示,创建一个列表与在 Java 语言中创建一个数组很类似。(注意,列表的第二项自动装箱为一个 Integer 类型。)
清单 12. 使用集合
collect = ['groovy', 29, 'here', 'groovy']
除了使列表更容易处理,Groovy 还为集合增加了几个新方法。这些方法使得,如统计值出现的次数、将整个列表结合到一起、对列表排序变得非常容易。可以在清单 13 中看到这些集合方法的使用。
清单 13. 使用 Groovy 集合
aCollect = [5, 9, 2, 2, 4, 5, 6]
println aCollect.join(' - ') // prints 5 - 9 - 2 - 2 - 4 - 5 - 6
println aCollect.count(2) // prints 2
println aCollect.sort() // prints [2, 2, 4, 5, 5, 6, 9]
Maps
像列表一样,映射也是一种在 Groovy 中非常容易处理的数据结构。清单 14 中的映射包含两个对象,键是 name 和 date。注意可以用不同的方式取得值。
清单 14. 处理映射
myMap = ["name" : "Groovy", "date" : new Date()]
println myMap["date"]
println myMap.date
范围
在处理集合时,很可能会大量使用 范围(Range)。 范围 实际上是一个很直观的概念,并且容易理解,利用它可以包含地或者排除地创建一组有序值。使用两个点 (..) 声明一个包含范围,用三个点 (...) 声明一个排除范围,如清单 15 所示。
清单 15. 处理范围
myRange = 29...32
myInclusiveRange = 2..5
println myRange.size() // prints 3
println myRange[0] // prints 29
println myRange.contains(32) //prints false
println myInclusiveRange.contains(5) //prints true
用范围实现循环
在循环结构中,范围可以实现相当巧妙的想法。在清单 16 中,将 aRange 定义为一个排除范围,循环打印 a、b、c 和 d。
清单 16. 用范围实现循环
aRange = 'a'...'e'
for (i in aRange){
println i
}
集合的其他功能
如果不熟悉 Python 和其他脚本语言,那么您在 Groovy 集合中发现的一些其他功能会让您印象深刻。例如,创建了集合后,可以用负数在列表中反向计数,如清单 17 所示。
清单 17. 负索引
aList = ['python', 'ruby', 'groovy']
println aList[-1] // prints groovy
println aList[-3] // prints python
Groovy 还让您可以用范围分割列表。分割可获得列表的准确子集,如清单 18 所示。
清单 18. 用范围分割
fullName = "Andrew James Glover"
mName = fullName[7...13]
print "middle name: " + mName // prints James
集合类似于 Ruby
如果愿意的话,还可以将 Groovy 集合作为 Ruby 集合。可以用类似 Ruby 的语法,以 << 语法附加元素、用 + 串接和用 - 对集合取差,甚至还可以用 * 语法处理集合的重复,如清单 19 所示。 注意,还可以用 == 比较集合。 清单 19. Ruby 风格的集合 collec = [1, 2, 3, 4, 5] collec << acol =" ['a','b','c']" coll =" [10," coll2 =" [12," coll3 =" coll" difcol =" [1,2,3]" str = "uncle man, uncle man" val =" it" x ="="" basecolor =" baseColor;" lavacolor =" lavaColor;" liquidcolor =" liquidColor;" model =" model;" llamp =" new" mylamp =" new" basecolor = "Silver"> " + line
}
因为文件实质上是一系列行、字符等,所以可以相当简单地迭代它们。eachLine 方法接收一个闭包并迭代文件的每一行,在这里是 File-IO-Example.txt。 以这种方式使用闭包是相当强大的,因为 Groovy 保证所有文件资源都是关闭的,不考虑任何异常。这意味着无需大量 try/catch/finally 子句就可以进行文件 IO!
高级编译
Groovy 脚本实际上是字节码级别的 Java 类。因此,可以容易地用 groovyc 编译 Groovy 脚本。可以通过命令行或者 Ant 使用 groovyc 以生成脚本的类文件。这些类可以用普通 java 命令运行,只要 classpath 包括 groovy.jar 和 asm.jar,这是 ObjectWeb 的字节码操纵框架。要了解更多编译 Groovy 的内容,请参阅 参考资料。
最大 RegEx
如果一种语言没有正则表达式处理,则它是没价值的。Groovy 使用 Java 平台的 java.util.regex 库 ?? 但是做了少量基本的改变。例如,Groovy 使您可以用 ~ 表达式创建 Pattern 对象,用 =~ 表达式创建 Matcher 对象,如清单 25 所示。
清单 25. Groovy RegEx
str = "Water, water, every where,
And all the boards did shrink;
Water, water, every where,
Nor any drop to drink."
if (str =~ 'water'){
println 'found a match'
}
ptrn = ~"every where"
nStr = (str =~ 'every where').replaceAll('nowhere')
println nStr
您可能已经注意到了,可以在上述清单中定义 String、str,而无需为每一新行添加结束引号和 +。这是因为 Groovy 放松了要求字符串串接的普通 Java 约束。运行这段 Groovy 脚本会对匹配 water 的情况打印出 true,然后打印出一节诗,其中所有出现 “every where”的地方都替换为 “nowhere”
结束语
像所有婴儿期的项目一样,Groovy 是正在发展的语言。习惯于使用 Ruby 和 Python (或者 Jython)的开发人员可能会怀念 mixins、脚本导入(尽管可以将所需要的可导入脚本编译为相应的 Java 类)和方法调用的命名参数等这些功能的方便性。 但是 Groovy 绝对是一种发展中的语言。随着其开发人员数量的增加,它很有可能结合这些功能及更多功能。
同时,Groovy 有很多优点。它很好地融合了 Ruby、Python 和 Smalltalk 的一些最有用的功能,同时保留了基于 Java 语言的核心语法。对于熟悉 Java 平台的开发人员,Groovy 提供了更简单的替代语言,且几乎不需要学习时间。对于刚接触 Java 平台的开发人员,它可以作为有更复杂语法和要求的 Java 语言的一个容易的入口点。
像在本系统讨论的其他语言一样,Groovy 不是要替代 Java 语言,而是作为它的另一种选择。与这里讨论的其他语言不一样,Groovy 遵循 Java 规范,这意味着它有可能与 Java 平台上的 Java 语言具有同等重要的作用。
在本月这一期 alt.lang.jre 文章中,介绍了 Groovy 的基本框架和语法,以及它的一些高级编程功能。下个月将介绍在 Java 开发人员中最受欢迎的脚本语言: JRuby。
注释:Groovy主页在:http://groovy.codehaus.org/
Tiger 中的注释,第 1 部分: 向 Java 代码中添加元数据
作者/编者, O'Reilly Media, Inc
2004 年 9 月
注释,J2SE 5.0 (Tiger) 中的新功能,将非常需要的元数据工具引入核心 Java 语言。该系列文章分为两部分,在这第 1 部分中,作者 Brett McLaughlin 解释了元数据如此有用的原因,向您介绍了 Java 语言中的注释,并研究了 Tiger 的内置注释。
编程的一个最新的趋势,尤其是在 Java 编程方面,是使用元数据。简单地说,元数据就是关于 数据的数据。元数据可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。许多元数据工具,如 XDoclet(请参阅 参考资料),将这些功能添加到核心 Java 语言中,暂时成为 Java 编程功能的一部分。
直到可以使用 J2SE 5.0(也叫做 Tiger,现在是第二个 beta 版本),核心 Java 语言才最接近具有 Javadoc 方法的元数据工具。您使用特殊的标签集合来标记代码,并执行 javadoc 命令来将这些标签转化成格式化的 HTML 页面,该页面说明标签所附加到的类。然而,Javadoc 是有缺陷的元数据工具,因为除了生成文档之外,您没有固定、实用、标准化的方式来将数据用于其他用途。HTML 代码经常混入到 Javadoc 输出中这一事实甚至更进一步降低了其用于任何其他目的的价值。
Tiger 通过名为注释 的新功能将一个更通用的元数据工具合并到核心 Java 语言中。注释是可以添加到代码中的修饰符,可以用于包声明、类型声明、构造函数、方法、字段、参数和变量。Tiger 包含内置注释,还支持您自己编写的定制注释。本文将概述元数据的优点并向您介绍 Tiger 的内置注释。本系列文章的 第 2 部分 将研究定制注释。我要感谢 O'Reilly Media, Inc.,他们非常慷慨地 允许我在本文中使用我关于 Tiger 的书籍的“注释”一章中的代码示例(请参阅 参考资料)。
元数据的价值
一般来说,元数据的好处分为三类:文档编制、编译器检查和代码分析。代码级文档最常被引用。元数据提供了一种有用的方法来指明方法是否取决于其他方法,它们是否完整,特定类是否必须引用其他类,等等。这确实非常有用,但对于将元数据添加到 Java 语言中来说,文档编制可能是最不 相关的理由。Javadoc 已经提供了非常容易理解和健壮的方法来文档化代码。另外,当已经存在文档编制工具,并且在大多数时候都工作得很好时,谁还要编写文档编制工具?
编译器检查
元数据更重要的优点是编译器可以使用它来执行基本的编译时检查。例如,您将在本文后面的 Override 注释 中看到 Tiger 引入了一个这样的注释,用于允许您指定一种方法覆盖超类中的另一种方法。Java 编译器可以确保在元数据中指明的行为实际发生在代码级别。如果从来没有找出过这种类型的 bug,这样做似乎有点傻,但是大多数年龄很大的 Java 编程老手都曾经花费至少多个晚上来查明他们的代码为什么不能用。当最后认识到方法的参数有错,且该方法实际上没有 覆盖超类中的方法时,您可能更感到难受。使用元数据的工具有助于轻松地查明这种类型的错误,从而可以节省那些晚上来看长期进行的 Halo 联赛。
代码分析
可以证明,任何好的注释或元数据工具的最好功能就是可以使用额外数据来分析代码。在一个简单的案例中,您可能构建代码目录,提供必需的输入类型并指明返回类型。但是,您可能想,Java 反射具有相同的优点;毕竟,可以为所有这些信息内省代码。这从表面上看似乎是正确的,但是在实际中通常不使用。许多时候,方法作为输入接受的或者作为输出返回的类型实际上不是该方法想要的类型。例如,参数类型可能是 Object,但方法可能仅使用Integer。这在好些情况下很容易发生,比如在方法被覆盖而超类使用常规参数声明方法时,还有正在进行许多序列化的系统中也容易发生。在这两种情况中,元数据可以指示代码分析工具,虽然参数类型是 Object,但 Integer 才是真正需要的。这类分析非常有用,但也不能夸大它的价值。
在更复杂的情况下,代码分析工具可以执行所有种类的额外任务。示例 du jour 是 Enterprise JavaBean (EJB) 组件。甚至简单 EJB 系统中的依赖性和复杂性都非常令人吃惊。您具有了 home 接口和远程接口,以及本地接口和本地 home 接口,还有一个实现类。保持所有这些类同步非常困难。但是,元数据可以提供这个问题的解决放案。好的工具(还是要提一下 XDoclet)可以管理所有这些依赖性,并确保无“代码级”连接、但有“逻辑级”捆绑的类保持同步。元数据在这里确实可以发挥它的作用。
注释的基本知识
现在已经了解了元数据的好处,我将介绍 Tiger 中的注释。注释采用“at”标记形式 (@),后面是注释名称。然后在需要数据时,通过 name=value 对向注释提供数据。每次使用这类表示法时,就是在生成注释。一段代码可能会有 10 个、50 个或更多的注释。不过,您将发现多个注释都可能使用相同的注释类型。类型是实际使用的结构,在特定上下文中,注释本身是该类型的具体使用(请参阅侧栏 注释或注释类型?)。
注释分为三个基本种类:
* 标记注释没有变量。注释显示简单,由名称标识,没有提供其他数据。例如,@MarkerAnnotation 是标记注释。它不包含数据,仅有注释名称。
* 单一值注释与标记注释类似,但提供一段数据。因为仅提供很少的一点数据,所以可以使用快捷语法(假设注释类型接受此语法):@SingleValueAnnotation("my data")。除了 @ 标记外,这应该与普通的 Java 方法调用很像。
* 完整注释有多个数据成员。因此,必须使用更完整的语法(注释不再像普通的 Java 方法):@FullAnnotation(var1="data value 1", var2="data value 2", var3="data value 3")。
除了通过默认语法向注释提供值外,还可以在需要传送多个值时使用名称-值对。还可以通过花括号为注释变量提供值数组。清单 1 显示了注释中的值数组的示例。
Google Adsense公益广告问题之二
Our contextual advertising system automatically
identifies the meaning and language of a page based on a variety of
factors. Our technology takes into account elements such as linguistics,
keyword analysis, word frequency, font size, and the overall link
structure of the web. In general, adding the AdSense ad code to pages that
contain a majority of content in a supported language will allow you to
serve paid Google ads.
简单翻译来讲:
我们的上下文关联广告系统根据几个因素自动标志页面上内容含义。我们的计算元素包括
语言学,关键词分析,单词频率,字体尺寸以及全面的web结构.一般AdSense广告代码加入包含我们支持的语言内容的页面将允许你提供已付费的Google 广告。
看来Google的广告策略是内容为王啊。良好的内容。中英文混合,是呼唤广告的最佳策略。
星期三, 九月 15, 2004
Free Language Grammar Parser /免费的语言语法解析工具
非常好的免费语言语法解析器.支持Java php等.
有时间好好看看.
星期二, 九月 14, 2004
Google Adsense公益广告问题/Google Adsense alternative ad and public service trouble
Google发放广告的流程:
你申请了adsense帐户后,google蜘蛛程序会自动抓去你的站点,并分析关键词adword到数据库中。
以前是一周分析一次,现在是一天一次。然后根据关键词找到google的客户广告,并发放到你的站点上。
所以,推断产生公益广告的原因。
1.你的网站内容不够丰富(最关键)。
内容太少,google 蜘蛛程序无法定位你的站点的明确适合目标客户
2.站点最好中英文混合.
方便google 蜘蛛分析。
3.要经常更新。
4.http://www.google.com/addurl.html去在google里加入你的网站!!!
解决办法。
使用google alternate ads是一个途径,这只在你可以从两个公司获取利润的情况下才有意义,否则只能是弥补版面的美观。通过google_alternate_ad="";google_alternate_color="#11111";
同样可以隐藏掉公益广告美化版面。
发email: mailto:adsense-support@google.com 寻找帮助.
星期一, 九月 13, 2004
In java How to Get Embed Groovy Environment variable number?
Example:
Binding tempBind=_shell.getContext();
java.util.Map allenv=tempBind.getVariables();
java.util.Set keys=allenv.keySet();
java.util.Iterator keylist=keys.iterator();
while(keylist.hasNext())
{
Object index=keylist.next();
System.out.println(index+":"+allenv.get(index));
}
星期日, 九月 12, 2004
星期五, 九月 10, 2004
Groovy 中文 FAQ
PreConditon:Groovy 1.0 Beta 6 jvm 1.4.2_04 windows XP
1. 如何声明一个Groovy 类似的方法或函数调用
Groovy没有明确的关键词类似Function或类似语法。
Groovy通过Closure块来实现常用功能库.
Example 1:
A={println “Hello,Wolrd”;
Println “String”.getBytes();
}
A();
Example 2:使用参数
ClosureA={
Name | println “你是”+Name;
}
ClosureA(“ Peter”);
2. 如何动态运行Groovy代码?
Q:如果把Groovy代码放在文件中或数据库中,或从用户输入,如何执行呢?
A:Groovy 代码放在文件中
可以通过CMI:groovy.bat 文件.groovy来运行.
如果是从Java语言中运行存放在文件中的groovy代码.必须用以下语法
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyShell;
import groovy.lang.Binding;
import groovy.lang.Closure;
// Create a class loader
GroovyClassLoader groovyLoader =
new GroovyClassLoader();
// Create the shell
GroovyShell shell =
new GroovyShell( groovyLoader, new Binding() );
如果定义的Groovy class就要用:
Class closureClass=grrovyLoader.loadClass(“groovy file.”);
如果groovy是业务逻辑代码:
GroovyShell shell = new GroovyShell( new Binding() );
shell.evaluate( new File( "GroovyXML4.groovy" ) );
// Get the calculateAmounts closure
Closure calc =
(Closure)shell.getVariable( "calculateAmounts" );
3. 如何判断一段Groovy代码是否语法正确?
Import groovy.lang.GroovyShell;
Import groovy.lang.Binding;
GroovyShell shell = new GroovyShell(new Binding());
String groovyScript=””;
try
{
shell.parse(groovyScript); //解析是否正确
}catch(Exception e)
{
return false;
}
return true;
4. 如何把字符串当作groovy代码看待?
GroovyShell shell =new GroovyShell(new Binding() );
codeString="import groovy.lang.*;
println 'this is test';
";
Script script = shell.parse(codeString);
script.run();
5. 用字符串构造groovy closure
codeString=”{ |basicinfo,employment,attendence| println “basicinfo:”+basicinfo;
println “employment:”+employment;
println “attendence”+attendence;
}
“;
block=shell.evaluate(codeString);
block("william","aaa",12);//Cool!!
6. 在Java中如何使用Groovy 对象?
GroovyShell _shell=new GroovyShell(new Binding());
//Test 1 From String 2 Closure Object
StringBuffer groovyCode=new StringBuffer().append("{"};
groovyCode.append("|name,sex,high|");//Parameter of Closure
groovyCode.append(" println \"你的名字:\"+name;");
groovyCode.append(" println \"性别:\"+sex;");
groovyCode.append(" println \"身高:\"+high;");
groovyCode.append(")");
Object[] params={new String("William"),new String("Male"),new Integer(10)};
Closure temp =(Closure) _shell.evaluate(groovyCode.toString());
temp.call(params);
7. 如何实现复杂对象传递.
Groovy中的Map对象为java.util.HashMap对象。
Map的初始化为[:]( list的初始化为[])
经典代码:
Query_SQL="select distinct contactphone,a.empid,businessrule from emp_M_basicInfo a inner join emp_M_SalaryBasicInfo a1,pay_M_catagoryitem b1 on a.factorycode=a1.factorycode and a.empid = a1.empid and a1.paycatagorycode=b1.paycatagorycode and a1.factorycode=b1.factorycode "
sql = Sql.newInstance("jdbc:mysql://localhost:3306/PCD","root","","org.gjt.mm.mysql.Driver");
rsetmap=[:]
sql.eachRow(Query_SQL,{rset|
metadata=rset.getMetaData();
tempmap=[:]
for ( index in 1..metadata.getColumnCount())
{
tempmap.put("${metadata.getColumnName(index).toLowerCase()}","${rset.getObject(index)}");
}
println tempmap
rsetmap.put(rset.getRow(),tempmap);
});
//println rsetmap.values().each{println it} //ok.
//println rsetmap.size();
testa=rsetmap.values();
try{
testa.each {println it.empid}
} catch(Exception e) {println "erro"+e.getMessage();}
星期六, 九月 04, 2004
星期五, 九月 03, 2004
J2sdk 1.4 Matcher.matches()和String.matches(String Regex)的区别.
微妙.
JDK 1.4中利用java.util.Regex来发现匹配的单词.
//\\b 表示单词分界符号.
import java.util.regex.*;
String targetStr = "a.factorycode,b.empid afactorycodeb";
String RegexStr="\\bfactorycode\\b";
Pattern p = Pattern.compile(RegexStr);
Matcher m = p.matcher(targetStr);
while ( (m.find()) ) { System.out.println("find");}
JSP使用JSTL来动态switch 语言信息或标签(label)
* 通过提交lang参数来动态切换语言包,注意红色部分,是技巧
*/
<c:choose>
<c:when test="${param.lang ne null}">
<c:set value="${param.lang}" var="lang" scope="request"/>
</c:when>
<c:otherwise>
<c:set value="zh" var="lang"/>
</c:otherwise>
</c:choose>
<%response.flushBuffer();%>
<fmt:setLocale value="${requestScope.lang}" scope="request" />
<fmt:setBundle basename="com.movalogic.resource.dictionary" scope="request" var="first"/>
<fmt:message key="HELLO_LABEL" bundle="${first}" />
BTW:由于Tomcat Container的 Cache原因.当使用JSTL setLocale设置语言后,当前browser显示的内容,就只能为这种语言,再次通过setLocale来设置语言,不起作用.
常见之法:修改 tomcat 系统web.xml中的有关JSP的编译部分,org.apache.jasper.servlet.JspServlet 设置其enablePooling=true
就可以避免setLocale多次不起作用了.