??xml version="1.0" encoding="utf-8" standalone="yes"?>国内不卡的二区三区中文字幕,国产美女福利在线,国产精品1区在线http://www.aygfsteel.com/EricGu/专注 学习 实践 创新zh-cnThu, 19 Jun 2025 15:18:32 GMTThu, 19 Jun 2025 15:18:32 GMT60ora10ginstant _客户端遇?system.data.oracleclient 需?oracle 客户端Y?.1.7 或更高版?/title><link>http://www.aygfsteel.com/EricGu/archive/2012/04/19/375255.html</link><dc:creator>Eric Gu</dc:creator><author>Eric Gu</author><pubDate>Thu, 19 Apr 2012 05:09:00 GMT</pubDate><guid>http://www.aygfsteel.com/EricGu/archive/2012/04/19/375255.html</guid><wfw:comment>http://www.aygfsteel.com/EricGu/comments/375255.html</wfw:comment><comments>http://www.aygfsteel.com/EricGu/archive/2012/04/19/375255.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/EricGu/comments/commentRss/375255.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/EricGu/services/trackbacks/375255.html</trackback:ping><description><![CDATA[     遇到System.Data.OracleClient 需?Oracle 客户端Y?8.1.7 或更高版本。一般第一反映都是会出处理  oracle_home 文gҎ限。可是有时时?不管你怎么摆弄权限Q怎么iisresetQ怎么重启电脑都解决不了,cmd  path 明明可以看到有oracle_home 路径啊。问题在于。环境变量中Q?ora10gInstant _客户端默认把变量d?Administrator 的用户变量了Q我们要做的是把  用户变量中的 Path ?转到 pȝ变量中的 Path 中?img src ="http://www.aygfsteel.com/EricGu/aggbug/375255.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/EricGu/" target="_blank">Eric Gu</a> 2012-04-19 13:09 <a href="http://www.aygfsteel.com/EricGu/archive/2012/04/19/375255.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 spring 2.5 注释驱动?ioc 功能 http://www.aygfsteel.com/EricGu/archive/2010/12/15/340791.htmlEric GuEric GuWed, 15 Dec 2010 06:40:00 GMThttp://www.aygfsteel.com/EricGu/archive/2010/12/15/340791.htmlhttp://www.aygfsteel.com/EricGu/comments/340791.htmlhttp://www.aygfsteel.com/EricGu/archive/2010/12/15/340791.html#Feedback0http://www.aygfsteel.com/EricGu/comments/commentRss/340791.htmlhttp://www.aygfsteel.com/EricGu/services/trackbacks/340791.html

在项目中使用Spring的注解,关于spring的注解,׃U注解方式,

Z注释QAnnotationQ的配置有越来越行的趋势,Spring 2.5 应q种势Q提供了完全Z注释配置 Bean、装?Bean 的功能,您可以用基于注释的 Spring IoC 替换原来Z XML 的配|。本文通过实例详细讲述?Spring 2.5 Z注释 IoC 功能的用?/p>

<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->

概述

注释配置相对?XML 配置h很多的优势:

  • 它可以充分利?Java 的反机制获取类l构信息Q这些信息可以有效减配|的工作。如使用 JPA 注释配置 ORM 映射Ӟ我们׃需要指?PO 的属性名、类型等信息Q如果关p表字段?PO 属性名、类型都一_您甚x需~写d属性映信息——因些信息都可以通过 Java 反射机制获取?
  • 注释?Java 代码位于一个文件中Q?XML 配置采用独立的配|文Ӟ大多数配|信息在E序开发完成后都不会调_如果配置信息?Java 代码攑֜一P有助于增强程序的内聚性。而采用独立的 XML 配置文gQ程序员在编写一个功能时Q往往需要在E序文g和配|文件中不停切换Q这U思维上的不连贯会降低开发效率?

因此在很多情况下Q注释配|比 XML 配置更受Ƣ迎Q注释配|有q一步流行的势。Spring 2.5 的一大增强就是引入了很多注释c,现在您已l可以用注释配|完成大部分 XML 配置的功能。在q篇文章里,我们向您讲qC用注释进?Bean 定义和依赖注入的内容?/p>

 

 

 

使用 @Autowired 注释

Spring 2.5 引入?@Autowired 注释Q它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作?/p>

Spring 通过一?BeanPostProcessor ?@Autowired q行解析Q所以要?@Autowired 起作用必M先在 Spring 容器中声?AutowiredAnnotationBeanPostProcessor Bean?/p>

 

 

在Spring中配|如下:

<!-- ?BeanPostProcessor 自动v作用Q对标注 @Autowired ?Bean q行自动注入 -->
    <bean class="org.springframework.beans.factory.annotation.
        AutowiredAnnotationBeanPostProcessor"/>
?Spring 容器启动ӞAutowiredAnnotationBeanPostProcessor 扫?Spring 容器中所?BeanQ当发现 Bean 中拥?@Autowired 注释时就扑ֈ和其匚wQ默认按cd匚wQ的 BeanQƈ注入到对应的地方中去?/p>

按照上面的配|,Spring 直接采?Java 反射机制?Boss 中的 car ?office q两个私有成员变量进行自动注入。所以对成员变量使用 @Autowired 后,您大可将它们?setter ҎQ?code>setCar() ?setOffice()Q从 Boss 中删除?/p>

当然Q您也可以通过 @Autowired Ҏ法或构造函数进行标注,

 

当候?Bean 数目不ؓ 1 时的应对Ҏ

在默认情况下使用 @Autowired 注释q行自动注入ӞSpring 容器中匹配的候?Bean 数目必须有且仅有一个。当找不C个匹配的 Bean ӞSpring 容器抛?BeanCreationException 异常Qƈ指出必须臛_拥有一个匹配的 Bean?/p>

 

当不能确?Spring 容器中一定拥有某个类?Bean Ӟ可以在需要自动注入该c?Bean 的地方可以?@Autowired(required = false)Q这{于告诉 SpringQ在找不到匹?Bean 时也不报错?/p>

 

一般情况下Q?@Autowired 的地斚w是需要注?Bean 的,使用了自动注入而又允许不注入的情况一般仅会在开发期或测试期到Q如Z快速启?Spring 容器Q仅引入一些模块的 Spring 配置文gQ,所?@Autowired(required = false) 会很用到?/p>

和找不到一个类型匹?Bean 相反的一个错误是Q如?Spring 容器中拥有多个候?BeanQSpring 容器在启动时也会抛出 BeanCreationException 异常?/p>

 

Spring 允许我们通过 @Qualifier 注释指定注入 Bean 的名Uͼq样歧义消除了Q可以通过下面的方法解军_常:


清单 13. 使用 @Qualifier 注释指定注入 Bean 的名U?/strong>

            @Autowired
            public void setOffice(@Qualifier("office")Office office) {
            this.office = office;
            }
            

@Qualifier("office") 中的 office ?Bean 的名Uͼ所?@Autowired ?@Qualifier l合使用Ӟ自动注入的策略就?byType 转变?byName 了?code>@Autowired 可以Ҏ员变量、方法以及构造函数进行注释,?@Qualifier 的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同Q所?Spring 不将 @Autowired ?@Qualifier l一成一个注释类。下面是Ҏ员变量和构造函数入参进行注释的代码Q?/p>

Ҏ员变量进行注释:

 

Ҏ员变量?@Qualifier 注释

            public class Boss {
            @Autowired
            private Car car;
            @Autowired
            @Qualifier("office")
            private Office office;
            …
            }
            

Ҏ造函数入参进行注释:


清单 15. Ҏ造函数变量?@Qualifier 注释

            public class Boss {
            private Car car;
            private Office office;
            @Autowired
            public Boss(Car car , @Qualifier("office")Office office){
            this.car = car;
            this.office = office ;
            }
            }
            

@Qualifier 只能?@Autowired l合使用Q是?@Autowired 有益的补充。一般来Ԍ@Qualifier Ҏ法签名中入参q行注释会降低代码的可读性,而对成员变量注释则相对好一些?/p>

 

使用 JSR-250 的注?/span>

Spring 不但支持自己定义?@Autowired 的注释,q支持几个由 JSR-250 规范定义的注释,它们分别?@Resource?code>@PostConstruct 以及 @PreDestroy?/p>

@Resource

@Resource 的作用相当于 @AutowiredQ只不过 @Autowired ?byType 自动注入Q面 @Resource 默认?byName 自动注入|了?code>@Resource 有两个属性是比较重要的,分别?name ?typeQSpring ?@Resource 注释?name 属性解析ؓ Bean 的名字,?type 属性则解析?Bean 的类型。所以如果?name 属性,则?byName 的自动注入策略,而?type 属性时则?byType 自动注入{略。如果既不指?name 也不指定 type 属性,q时通过反射机制使用 byName 自动注入{略?/p>

Resource 注释cM?Spring 发布包的 lib/j2ee/common-annotations.jar cd中,因此在用之前必d其加入到目的类库中。来看一个?@Resource 的例子:


清单 16. 使用 @Resource 注释?Boss.java

            package com.baobaotao;
            import javax.annotation.Resource;
            public class Boss {
            // 自动注入cd?Car ?Bean
            @Resource
            private Car car;
            // 自动注入 bean 名称?office ?Bean
            @Resource(name = "office")
            private Office office;
            }
            

一般情况下Q我们无需使用cM?@Resource(type=Car.class) 的注释方式,因ؓ Bean 的类型信息可以通过 Java 反射从代码中获取?/p>

要让 JSR-250 的注释生效,除了?Bean cM标注q些注释外,q需要在 Spring 容器中注册一个负责处理这些注释的 BeanPostProcessorQ?/p>

 

<bean
            class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
            

CommonAnnotationBeanPostProcessor 实现?BeanPostProcessor 接口Q它负责扫描使用?JSR-250 注释?BeanQƈ对它们进行相应的操作?/p>

@PostConstruct ?@PreDestroy

Spring 容器中的 Bean 是有生命周期的,Spring 允许?Bean 在初始化完成后以?Bean 销毁前执行特定的操作,您既可以通过实现 InitializingBean/DisposableBean 接口来定制初始化之后 / 销毁之前的操作ҎQ也可以通过 <bean> 元素?init-method/destroy-method 属性指定初始化之后 / 销毁之前调用的操作Ҏ。关?Spring 的生命周期,W者在《精?Spring 2.x—企业应用开发精解》第 3 章进行了详细的描qͼ有兴的读者可以查阅?/p>

JSR-250 为初始化之后/销毁之前方法的指定定义了两个注释类Q分别是 @PostConstruct ?@PreDestroyQ这两个注释只能应用于方法上。标注了 @PostConstruct 注释的方法将在类实例化后调用Q而标注了 @PreDestroy 的方法将在类销毁之前调用?/p>


清单 17. 使用 @PostConstruct ?@PreDestroy 注释?Boss.java

            package com.baobaotao;
            import javax.annotation.Resource;
            import javax.annotation.PostConstruct;
            import javax.annotation.PreDestroy;
            public class Boss {
            @Resource
            private Car car;
            @Resource(name = "office")
            private Office office;
            @PostConstruct
            public void postConstruct1(){
            System.out.println("postConstruct1");
            }
            @PreDestroy
            public void preDestroy1(){
            System.out.println("preDestroy1");
            }
            …
            }
            

您只需要在Ҏ前标?@PostConstruct ?@PreDestroyQ这些方法就会在 Bean 初始化后或销毁之前被 Spring 容器执行了?/p>

我们知道Q不是通过实现 InitializingBean/DisposableBean 接口Q还是通过 <bean> 元素?init-method/destroy-method 属性进行配|,都只能ؓ Bean 指定一个初始化 / 销毁的Ҏ。但是?@PostConstruct ?@PreDestroy 注释却可以指定多个初始化 / 销毁方法,那些被标?@PostConstruct ?@PreDestroy 注释的方法都会在初始?/ 销毁时被执行?/p>

通过以下的测试代码,您将可以看到 Bean 的初始化 / 销毁方法是如何被执行的Q?/p>


清单 18. 试cM?/strong>

            package com.baobaotao;
            import org.springframework.context.support.ClassPathXmlApplicationContext;
            public class AnnoIoCTest {
            public static void main(String[] args) {
            String[] locations = {"beans.xml"};
            ClassPathXmlApplicationContext ctx =
            new ClassPathXmlApplicationContext(locations);
            Boss boss = (Boss) ctx.getBean("boss");
            System.out.println(boss);
            ctx.destroy();// 关闭 Spring 容器Q以触发 Bean 销毁方法的执行
            }
            }
            

q时Q您看到标注了 @PostConstruct ?postConstruct1() Ҏ在 Spring 容器启动Ӟ创徏 Boss Bean 的时候被触发执行Q而标注了 @PreDestroy 注释?preDestroy1() Ҏ在 Spring 容器关闭前销?Boss Bean 的时候被触发执行?/p>





回页?/span>

使用 <context:annotation-config/> 化配|?/span>

Spring 2.1 d了一个新?context ?Schema 命名I间Q该命名I间Ҏ释驱动、属性文件引入、加载期l入{功能提供了便捷的配|。我们知道注释本w是不会做Q何事情的Q它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作h?

而我们前面所介绍?AutowiredAnnotationBeanPostProcessor ?CommonAnnotationBeanPostProcessor 是处理q些注释元数据的处理器。但是直接在 Spring 配置文g中定义这?Bean 昑־比较W拙。Spring 为我们提供了一U方便的注册q些 BeanPostProcessor 的方式,q就?<context:annotation-config/>。请看下面的配置Q?/p>


清单 19. 调整 beans.xml 配置文g

            <?xml version="1.0" encoding="UTF-8" ?>
            <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:context="http://www.springframework.org/schema/context"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-2.5.xsd">
            <context:annotation-config/>
            <bean id="boss" class="com.baobaotao.Boss"/>
            <bean id="office" class="com.baobaotao.Office">
            <property name="officeNo" value="001"/>
            </bean>
            <bean id="car" class="com.baobaotao.Car" scope="singleton">
            <property name="brand" value=" U旗 CA72"/>
            <property name="price" value="2000"/>
            </bean>
            </beans>
            

<context:annotationconfig/> 隐式地?Spring 容器注册 AutowiredAnnotationBeanPostProcessor?code>CommonAnnotationBeanPostProcessor?code>PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor q?4 ?BeanPostProcessor?/p>

在配|文件中使用 context 命名I间之前Q必d <beans> 元素中声?context 命名I间?/p>





回页?/span>

使用 @Component

虽然我们可以通过 @Autowired ?@Resource ?Bean cM使用自动注入功能Q但?Bean q是?XML 文g中通过 <bean> q行定义 —?也就是说Q在 XML 配置文g中定?BeanQ通过 @Autowired ?@Resource ?Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。能否也通过注释定义 BeanQ从 XML 配置文g中完全移?Bean 定义的配|呢Q答案是肯定的,我们通过 Spring 2.5 提供?@Component 注释可以达到这个目标了?/p>

下面Q我们完全用注释定?Bean q完?Bean 之间装配Q?/p>


清单 20. 使用 @Component 注释?Car.java

            package com.baobaotao;
            import org.springframework.stereotype.Component;
            @Component
            public class Car {
            …
            }
            

仅需要在cd义处Q?@Component 注释可以将一个类定义?Spring 容器中的 Bean。下面的代码?Office 定义Z?BeanQ?/p>


清单 21. 使用 @Component 注释?Office.java

            package com.baobaotao;
            import org.springframework.stereotype.Component;
            @Component
            public class Office {
            private String officeNo = "001";
            …
            }
            

q样Q我们就可以?Boss cM通过 @Autowired 注入前面定义?Car ?Office Bean 了?/p>


清单 22. 使用 @Component 注释?Boss.java

            package com.baobaotao;
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.beans.factory.annotation.Required;
            import org.springframework.beans.factory.annotation.Qualifier;
            import org.springframework.stereotype.Component;
            @Component("boss")
            public class Boss {
            @Autowired
            private Car car;
            @Autowired
            private Office office;
            …
            }
            

@Component 有一个可选的入参Q用于指?Bean 的名Uͼ?Boss 中,我们将 Bean 名称定义?#8220;boss”。一般情况下QBean 都是 singleton 的,需要注?Bean 的地方仅需要通过 byType {略可以自动注入了Q所以大可不必指?Bean 的名U?/p>

在?@Component 注释后,Spring 容器必须启用cL描机制以启用注释驱动 Bean 定义和注释驱?Bean 自动注入的策略。Spring 2.5 ?context 命名I间q行了扩展,提供了这一功能Q请看下面的配置Q?/p>


清单 23. 化版?beans.xml

            <?xml version="1.0" encoding="UTF-8" ?>
            <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:context="http://www.springframework.org/schema/context"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-2.5.xsd">
            <context:component-scan base-package="com.baobaotao"/>
            </beans>
            

q里Q所有通过 <bean> 元素定义 Bean 的配|内容已l被U除Q仅需要添加一?<context:component-scan/> 配置px有问题了——Spring XML 配置文g得到了极致的化(当然配置元数据还是需要的Q只不过以注释Ş式存在Ş了)?lt;context:component-scan/> ?base-package 属性指定了需要扫描的cdQ类包及光归子包中所有的c都会被处理?/p>

<context:component-scan/> q允许定义过滤器基包下的某些类U_或排除。Spring 支持以下 4 U类型的qo方式Q通过下表说明Q?/p>


?1. 扫描qo方式

qo器类?/th> 说明
注释 假如 com.baobaotao.SomeAnnotation 是一个注释类Q我们可以将使用该注释的c过滤出来?/td>
cd指定 通过全限定类名进行过滤,如您可以指定?com.baobaotao.Boss U_扫描Q而将 com.baobaotao.Car 排除在外?/td>
正则表达?/td> 通过正则表达式定义过滤的c,如下所C: com\.baobaotao\.Default.*
AspectJ 表达?/td> 通过 AspectJ 表达式定义过滤的c,如下所C: com. baobaotao..*Service+

下面是一个简单的例子Q?/p>

 

<context:component-scan base-package="com.baobaotao">
            <context:include-filter type="regex"
            expression="com\.baobaotao\.service\..*"/>
            <context:exclude-filter type="aspectj"
            expression="com.baobaotao.util..*"/>
            </context:component-scan>
            

值得注意的是 <context:component-scan/> 配置不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时q启用了注释驱动自动注入的功能(卌隐式地在内部注册?AutowiredAnnotationBeanPostProcessor ?CommonAnnotationBeanPostProcessorQ,因此当?<context:component-scan/> 后,可以将 <context:annotation-config/> U除了?/p>

默认情况下通过 @Component 定义?Bean 都是 singleton 的,如果需要用其它作用范围的 BeanQ可以通过 @Scope 注释来达到目标,如以下代码所C:


清单 24. 通过 @Scope 指定 Bean 的作用范?/strong>

            package com.baobaotao;
            import org.springframework.context.annotation.Scope;
            …
            @Scope("prototype")
            @Component("boss")
            public class Boss {
            …
            }
            

q样Q当?Spring 容器中获?boss Bean Ӟ每次q回的都是新的实例了?/p>





回页?/span>

采用hҎ语义的注?/span>

Spring 2.5 中除了提?@Component 注释外,q定义了几个拥有Ҏ语义的注释,它们分别是:@Repository?code>@Service ?@Controller。在目前?Spring 版本中,q?3 个注释和 @Component 是等效的Q但是从注释cȝ命名上,很容易看 3 个注释分别和持久层、业务层和控制层QWeb 层)相对应。虽然目前这 3 个注释和 @Component 相比没有什么新意,?Spring 在以后的版本中为它们添加特D的功能。所以,如果 Web 应用E序采用了经典的三层分层l构的话Q最好在持久层、业务层和控制层分别采用 @Repository?code>@Service ?@Controller 对分层中的类q行注释Q而用 @Component 寚w些比较中立的c进行注释?/p>





回页?/span>

注释配置?XML 配置的适用场合

是否有了q些 IOC 注释Q我们就可以完全摒除原来 XML 配置的方式呢Q答案是否定的。有以下几点原因Q?/p>

  • 注释配置不一定在先天上优?XML 配置。如?Bean 的依赖关pL固定的,Q如 Service 使用了哪几个 DAO c)Q这U配|信息不会在部v时发生调_那么注释配置优于 XML 配置Q反之如果这U依赖关pM在部|时发生调整QXML 配置昄又优于注释配|,因ؓ注释是对 Java 源代码的调整Q您需要重新改写源代码q新编译才可以实施调整?
  • 如果 Bean 不是自己~写的类Q如 JdbcTemplate?code>SessionFactoryBean {)Q注释配|将无法实施Q此?XML 配置是唯一可用的方式?
  • 注释配置往往是类U别的,?XML 配置则可以表现得更加灉|。比如相比于 @Transaction 事务注释Q?aop/tx 命名I间的事务配|更加灵zd单?

所以在实现应用中,我们往往需要同时用注释配|和 XML 配置Q对于类U别且不会发生变动的配置可以优先考虑注释配置Q而对于那些第三方cM及容易发生调整的配置则应优先考虑使用 XML 配置。Spring 会在具体实施 Bean 创徏?Bean 注入之前这两种配置方式的元信息融合在一赗?/p>





回页?/span>

Spring ?2.1 以后Ҏ释配|提供了强力的支持,注释配置功能成ؓ Spring 2.5 的最大的亮点之一。合理地使用 Spring 2.5 的注释配|,可以有效减少配置的工作量Q提高程序的内聚性。但是这q不意味着传统 XML 配置走向消亡,在第三方c?Bean 的配|,以及那些诸如数据源、缓存池、持久层操作模板cR事务管理等内容的配|上QXML 配置依然拥有不可替代的地位?/p>

Eric Gu 2010-12-15 14:40 发表评论
]]>
Spring控制反{的通俗解释【{?/title><link>http://www.aygfsteel.com/EricGu/archive/2010/12/15/340757.html</link><dc:creator>Eric Gu</dc:creator><author>Eric Gu</author><pubDate>Wed, 15 Dec 2010 03:39:00 GMT</pubDate><guid>http://www.aygfsteel.com/EricGu/archive/2010/12/15/340757.html</guid><wfw:comment>http://www.aygfsteel.com/EricGu/comments/340757.html</wfw:comment><comments>http://www.aygfsteel.com/EricGu/archive/2010/12/15/340757.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/EricGu/comments/commentRss/340757.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/EricGu/services/trackbacks/340757.html</trackback:ping><description><![CDATA[<div class="wmqeeuq" id="blog_text" class="cnt"> <p><font size="2" face="宋体">什么叫控制反{呢?套用好莱坞的一句名a是Q你呆着别动Q到时我会找你?<br /> 什么意思呢Q就好比一个皇帝和太监 <br /> </font><font size="2"><font face="宋体"><font color="#3366ff">有一天皇帝想宠幸某个女Q于是跟太监_今夜我要宠幸女 <br /> 皇帝往往不会告诉太监Q今晚几点会回宫Q会回哪张龙床,他只会告诉太监他要哪位美?/font> <br /> </font></font><font size="2"><font face="宋体"><font color="#ff6600">其它一切都交由太监d排,C晚上皇帝回宫Ӟ自然会有女出现在皇帝的龙床?<br /> q就是控制反转,而把女送到皇帝的寝宫里面去是注射</font> <br /> <font color="#ff0000">太监是是框枉面的注射控制器类</font>BeanFactoryQ负责找到美奛_ƈ送到龙床上去 <br /> <font color="#ff0000">整个后宫可以看成是Spring框架</font>Q美奛_是Spring控制下的JavaBean <br /> </font></font><font color="#339966" size="2" face="宋体">而传l的模式是一个饥渴男L姐出台 <br /> </font><font size="2"><font face="宋体"><font color="#3366ff">N班,帮助l介l一个云云,于是领班开始给他张|?br /> 介绍一个合适的l他Q完事后Q再把小姐还l领班,下次再来</font> <br /> </font></font><font size="2"><font face="宋体"><font color="#ff6600">q个q程中,领班是查询上下文ContextQ领班的一个职能就是给客户扑ֈ他们所要的姐 <br /> q就是lookup()ҎQ领班手中的姐名录是JNDI//Java Naming and Directory Interface <br /> </font><font color="#ff0000">姐是EJB</font>Q?font color="#0000ff">饥h客户?/font>Q?font color="#ff0000">青楼是EJB容器</font> <br /> 看到区别了么Q?/font></font></p> <p><font size="2"><font color="#993366" face="宋体">饥男去扑ְ姐出台很ȝQ不仅得找,用完后还得把姐l还回去</font></font></p> <p><font color="#ff00ff"><font face="宋体"><font size="2">而皇帝爽MQ什么都不用,交给太监d理,控制权{Ud太监手中M</font><font size="2">而不是皇帝,</font></font></font></p> <p><font color="#ff00ff"><font size="2" face="宋体">必要时候由太监l注进d可以?/font></font></p> </div> <br /> <img src ="http://www.aygfsteel.com/EricGu/aggbug/340757.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/EricGu/" target="_blank">Eric Gu</a> 2010-12-15 11:39 <a href="http://www.aygfsteel.com/EricGu/archive/2010/12/15/340757.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[hibernate]注解的说?/title><link>http://www.aygfsteel.com/EricGu/archive/2010/12/14/340650.html</link><dc:creator>Eric Gu</dc:creator><author>Eric Gu</author><pubDate>Tue, 14 Dec 2010 07:31:00 GMT</pubDate><guid>http://www.aygfsteel.com/EricGu/archive/2010/12/14/340650.html</guid><wfw:comment>http://www.aygfsteel.com/EricGu/comments/340650.html</wfw:comment><comments>http://www.aygfsteel.com/EricGu/archive/2010/12/14/340650.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/EricGu/comments/commentRss/340650.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/EricGu/services/trackbacks/340650.html</trackback:ping><description><![CDATA[/**<br />  * <br />  * @author liuguangyi<br />  * @content  ejb3注解的API定义在javax.persistence.*包里面?br />  * <br />  * 注释说明Q?br />  * @Entity —?一个类声明Z个实体bean(即一个持久化POJOc?<br />  * @Id —?注解声明了该实体bean的标识属性(对应表中的主键)?br />  * @Table —?注解声明了该实体bean映射指定的表QtableQ?目录QcatalogQ和schema的名?br />  * @Column —?注解声明了属性到列的映射。该注解有如下的属?br />  *  name  可选,列名Q默认值是属性名Q?br />  *  unique 可选,是否在该列上讄唯一U束Q默认值falseQ?br />  *  nullable 可选,是否讄该列的值可以ؓI(默认值falseQ?br />  *  insertable 可选,该列是否作ؓ生成的insert语句中的一个列Q默认值trueQ?br />  *  updatable 可选,该列是否作ؓ生成的update语句中的一个列Q默认值trueQ?br />  *  columnDefinition 可选,个特定列覆盖sql ddl片段Q这可能D无法在不同数据库间移植)<br />  *  table 可选,定义对应的表Q默认ؓ主表Q?br />  *  length 可选,列长度(默认?55Q?br />  *  precision 可选,列十q制_ֺQdecimal precision)(默认?Q?br />  *  scale 可选,如果列十q制数D_decimal scaleQ可用,在此讄Q默认?Q?br />  * @GeneratedValue —?注解声明了主键的生成{略。该注解有如下属?br />  *  strategy 指定生成的策略(JPA定义的)Q这是一个GenerationType。默认是GenerationType. AUTO<br />  *   GenerationType.AUTO 主键q序控?br />  *   GenerationType.TABLE 使用一个特定的数据库表格来保存主键<br />  *   GenerationType.IDENTITY 主键由数据库自动生成Q主要是自动增长cdQ?br />  *   GenerationType.SEQUENCE Ҏ底层数据库的序列来生成主键,条g是数据库支持序列。(q个D与generator一起用)<br />  *  generator 指定生成主键使用的生成器Q可能是orcale中的序列Q?br />  * @SequenceGenerator —?注解声明了一个数据库序列。该注解有如下属?br />  *  name 表示该表主键生成{略名称Q它被引用在@GeneratedValue中设|的“gernerator”g<br />  *  sequenceName 表示生成{略用到的数据库序列名称?br />  *  initialValue 表示主键初始|默认?.<br />  *  allocationSize 每次主键值增加的大小Q例如设|成1Q则表示每次创徏新记录后自动?Q默认ؓ50.<br />  * @GenericGenerator —?注解声明了一个hibernate的主键生成策略。支持十三种{略。该注解有如下属?br />  *  name 指定生成器名U?br />  *  strategy 指定具体生成器的cdQ指定生成策略)?br />  *  parameters 得到strategy指定的具体生成器所用到的参数?br />  *    其十三种{略Qstrategy属性的|如下Q?br />  *   1.native 对于orcale采用Sequence方式Q对于MySQL和SQL Server采用identity(处境主键生成机制)Q?br />  *     native是主键的生成工作由数据库完成,hibernate不管Q很常用Q?br />  *     例:@GeneratedValue(generator = "paymentableGenerator")    <br />  *          @GenericGenerator(name = "paymentableGenerator", strategy = "native")<br />  *      2.uuid 采用128位的uuid法生成主键Quuid被编码ؓ一?2?6q制数字的字W串。占用空间大Q字W串cdQ?br />  *       例:@GeneratedValue(generator = "paymentableGenerator")    <br />  *          @GenericGenerator(name = "paymentableGenerator", strategy = "uuid")<br />  *      3.hilo 要在数据库中建立一张额外的表,默认表名为hibernate_unque_keyQ默认字DؓintegercdQ名U是next_hiQ比较少用)<br />  *       例:@GeneratedValue(generator = "paymentableGenerator")    <br />  *          @GenericGenerator(name = "paymentableGenerator", strategy = "hilo")<br />  *      4.assigned 在插入数据的时候主键由E序处理Q很常用Q,q是<generator>元素没有指定时的默认生成{略。等同于JPA中的AUTO?br />  *       例:@GeneratedValue(generator = "paymentableGenerator")    <br />  *          @GenericGenerator(name = "paymentableGenerator", strategy = "assigned")<br />  *      5.identity 使用SQL Server和MySQL的自增字D,q个Ҏ不能攑ֈOracle中,Oracle不支持自增字D,要设定sequence(MySQL和SQL Server中很常用)。等同于JPA中的IDENTITY<br />  *       例:@GeneratedValue(generator = "paymentableGenerator")    <br />  *          @GenericGenerator(name = "paymentableGenerator", strategy = "identity")<br />  *      6.select 使用触发器生成主键(主要用于早期的数据库主键生成机制Q少用)<br />  *       例:@GeneratedValue(generator = "paymentableGenerator")    <br />  *          @GenericGenerator(name = "paymentableGenerator", strategy = "select")<br />  *      7.sequence 调用谨慎数据库的序列来生成主键,要设定序列名Q不然hibernate无法扑ֈ?br />  *       例:@GeneratedValue(generator = "paymentableGenerator")   <br />  *   @GenericGenerator(name = "paymentableGenerator", strategy = "sequence",    <br />  *    parameters = { @Parameter(name = "sequence", value = "seq_payablemoney") })<br />  *  8.seqhilo 通过hilo法实现Q但是主键历史保存在Sequence中,适用于支持Sequence的数据库Q如Orcale(比较用Q?<br />  *  例:@GeneratedValue(generator = "paymentableGenerator")   <br />  *    @GenericGenerator(name = "paymentableGenerator", strategy = "seqhilo",    <br />  *    parameters = { @Parameter(name = "max_lo", value = "5") })<br />  *  9.increnment 插入数据的时候hibernate会给主键d一个自增的主键Q但是一个hibernate实例q护一个计数器Q所以在多个实例q行的时候不能用这个方法?br />  *   例:@GeneratedValue(generator = "paymentableGenerator")    <br />  *          @GenericGenerator(name = "paymentableGenerator", strategy = "increnment")<br />  *      10.foreign 使用另一个相关的对象的主键。通常?lt;on<wbr>e-to-on<wbr>e>联合h使用?br />  *      例:@Id    <br />  *    @GeneratedValue(generator = "idGenerator")   <br />  *    @GenericGenerator(name = "idGenerator", strategy = "foreign",    <br />  *         parameters = { @Parameter(name = "property", value = "info") })    <br />  *    Integer id;<br />  *   @On<wbr>eToOne  <br />  *   EmployeeInfo info;<br />  *  11.guid 采用数据库底层的guid法机制Q对应MySQL的uuid()函数QSQL Server的newid()函数QORCALE的rawtohex(sys_guid())函数{?br />  *  例:@GeneratedValue(generator = "paymentableGenerator")     <br />  *    @GenericGenerator(name = "paymentableGenerator", strategy = "guid") <br />  *  12.uuid.hex 看uudi,用uuid替换<br />  *    例:@GeneratedValue(generator = "paymentableGenerator")     <br />  *    @GenericGenerator(name = "paymentableGenerator", strategy = "uuid.hex")<br />  *  13.sequence-identity sequence{略的扩展,采用立即索策略来获取sequence|需要JDBC3.0和JDK4以上Q含1.4Q版?br />  *       例:@GeneratedValue(generator = "paymentableGenerator")   <br />  *   @GenericGenerator(name = "paymentableGenerator", strategy = "sequence-identity",    <br />  *         parameters = { @Parameter(name = "sequence", value = "seq_payablemoney") })  <br />  *      <br />  * @On<wbr>eToOne 讄一对一个关联。cascade属性有五个?只有CascadeType.ALL好用Q很奇?Q分别是CascadeType.PERSIST(U联新徏)QCascadeType.REMOVEQ联删除)QCascadeType.REFRESHQ联刷斎ͼQCascadeType.MERGEQ联更斎ͼQCascadeType.ALLQ全部四)<br />  *    Ҏ一<br />  *     主表Q??@On<wbr>eToOne(cascade = CascadeType.ALL)<br />  *      @PrimaryKeyJoinColumn<br />  *      public 从表c?get从表c?){return 从表对象}<br />  *      从表Q没有主表类?br />  *      注意Q这U方法要求主表与从表的主键值想对应?br />  *   Ҏ?br />  *      主表Q?@On<wbr>eToOne(cascade = CascadeType.ALL)<br />  *          @JoinColumn(name="主表外键") //q里指定的是数据库中的外键字Dc?br />  *          public 从表c?get从表c?){return 从表c}<br />  *      从表Q@On<wbr>eToOne(mappedBy = "主表cM的从表属?)//例主表User中有一个从表属性是Heartcd的heartQ这里就填heart<br />  *          public 主表c?get主表c?){return 主表对象}<br />  *      注意Q@JoinColumn是可选的。默认值是从表变量?"_"+从表的主键(注意Q这里加的是主键。而不是主键对应的变量Q?br />  * Ҏ?br />  *      主表Q@On<wbr>eToOne(cascade=CascadeType.ALL)<br />  *          @JoinTable( name="兌表名",<br />  *    joinColumns = @JoinColumn(name="主表外键"),<br />  *    inverseJoinColumns = @JoinColumns(name="从表外键")<br />  *          )<br />  *      从表Q@On<wbr>eToOne(mappedBy = "主表cM的从表属?)//例主表User中有一个从表属性是Heartcd的heartQ这里就填heart<br />  *          public 主表c?get主表c?){return 主表对象}    <br />  *  @ManyToOne 讄多对一兌<br />  *    Ҏ一       <br />  *    @ManyToOne(cascade={CasCadeType.PERSIST,CascadeType.MERGE})<br />  *    @JoinColumn(name="外键")<br />  *    public 主表c?get主表c?){return 主表对象}<br />  *    Ҏ?br />  *    @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE})<br />  *    @JoinTable(name="兌表名"Q?br />  *     joinColumns = @JoinColumn(name="主表外键"),<br />  *     inverseJoinColumns = @JoinColumns(name="从表外键")<br />  *    )<br />  *  @On<wbr>eToMany 讄一对多兌。cascade属性指定关联?参考@On<wbr>eToOne中的说明。fetch指定是否延迟加蝲QgؓFetchType.LAZY表示延迟QؓFetchType.EAGER表示立即加蝲<br />  *    Ҏ一     使用q种配置Q在?#8220;一?#8221;d“多端”Ӟ不会修改“多端”的外键。在“一?#8221;加蝲Ӟ不会得到“多端”。如果用gq加载,在读“多端”列表时会出异常,立即加蝲在得到多端时Q是一个空集合Q集合元素ؓ0Q?br />  *    “一?#8221;配置<br />  *    @On<wbr>eToMany(mappedBy="“多端”的属?)<br />  *    public List<“多端”c?gt; get“多端”列表(){return “多端”列表}<br />  *    “多端”配置参考@ManyToOne.     <br />  *    Ҏ?br />  *    “一?#8221;配置<br />  *    @On<wbr>eToMany(mappedBy="“多端”的属?)<br />  *    @MapKey(name="“多端”做ؓKey的属?)<br />  *    public Map<“多端”做ؓKey的属性的c?主表c?gt; get“多端”列表Q){return “多端”列表}<br />  *    “多端”配置参考@ManyToOne. <br />  *    Ҏ?使用q种配置Q在?#8220;一?#8221;d“多端”Ӟ可以修改“多端”的外键?br />  *    “一?#8221;配置<br />  *    @On<wbr>eToMany<br />  *    @JoinColumn(name="“多端”外键") <br />  *    public List<“多端”c?gt; get“多端”列表(){return “多端”列表}<br />  *    “多端”配置参考@ManyToOne.     <br />  *    <br />  *   <br />  */ <img src ="http://www.aygfsteel.com/EricGu/aggbug/340650.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/EricGu/" target="_blank">Eric Gu</a> 2010-12-14 15:31 <a href="http://www.aygfsteel.com/EricGu/archive/2010/12/14/340650.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java语法ȝ - Ҏhttp://www.aygfsteel.com/EricGu/archive/2009/06/30/284798.htmlEric GuEric GuTue, 30 Jun 2009 09:17:00 GMThttp://www.aygfsteel.com/EricGu/archive/2009/06/30/284798.htmlhttp://www.aygfsteel.com/EricGu/comments/284798.htmlhttp://www.aygfsteel.com/EricGu/archive/2009/06/30/284798.html#Feedback0http://www.aygfsteel.com/EricGu/comments/commentRss/284798.htmlhttp://www.aygfsteel.com/EricGu/services/trackbacks/284798.html
1、重写只能出现在l承关系之中。当一个类l承它的父类ҎӞ都有Z重写该父cȝҎ。一个特例是父类的方法被标识为final。重写的主要优点是能够定义某个子cdҎ的行为?br />     class Animal {
        public void eat(){
            System.out.println ("Animal is eating.");
        }
    }
    
    class Horse extends Animal{
        public void eat(){
            System.out.println ("Horse is eating.");
        }
    }

2、对于从父类l承来的抽象ҎQ要么在子类用重写的方式设计该方法,要么把子cM标识为抽象的。所以抽象方法可以说是必要被重写的Ҏ?br />
3、重写的意义?br /> 重写Ҏ可以实现多态,用父cȝ引用来操U子cd象,但是在实际运行中对象运行其自己Ҏ的方法?br />     public class Test {
        public static void main (String[] args) {
            Animal h = new Horse();
            h.eat();    
        }
    }

    class Animal {
        public void eat(){
            System.out.println ("Animal is eating.");
        }
    }
    
    class Horse extends Animal{
        public void eat(){
            System.out.println ("Horse is eating.");
        }
        public void buck(){
        }
    }

一个原则是Q用了什么引用,~译器就会只调用引用cL拥有的方法。如果调用子cȝ有的ҎQ如上例的h.buck(); ~译器会抱怨的。也是_~译器只看引用类型,而不是对象类型?br />
4、重写方法的规则?br /> 若想实现一个合格重写方法,而不是重载,那么必须同时满下面的要求!

A、重写规则之一Q重写方法不能比被重写方法限制有更严格的讉KU别?br /> Q但是可以更q泛Q比如父cL法是包访问权限,子类的重写方法是public讉K权限。)
比如QObjectcL个toString()ҎQ开始重写这个方法的时候我们d易忘记public修饰W,~译器当然不会放qQ何教训我们的Z。出错的原因是Q没有加M讉K修饰W的Ҏh包访问权限,包访问权限比public当然要严gQ所以编译器会报错的?br />
B、重写规则之二:参数列表必须与被重写Ҏ的相同?br /> 重写有个孪生的弟弟叫重蝲Q也是后面要出场的。如果子cL法的参数与父cd应的Ҏ不同Q那么就是你认错ZQ那是重载,不是重写?br />
C、重写规则之三:q回cd必须与被重写Ҏ的返回类型相同?br /> 父类ҎAQvoid eat(){}  子类ҎBQint eat(){}  两者虽然参数相同,可是q回cd不同Q所以不是重写?br /> 父类ҎAQint eat(){}   子类ҎBQlong eat(){}  q回cd虽然兼容父类Q但是不同就是不同,所以不是重写?br />
D、重写规则之四:重写Ҏ不能抛出新的异常或者比被重写方法声明的查异常更q的查异常。但是可以抛出更,更有限或者不抛出异常?br />     import java.io.*;
    public class Test {
        public static void main (String[] args) {
            Animal h = new Horse();
            try {
                h.eat();    
            }
            catch (Exception e) {
            }
        }
    }

    class Animal {
        public void eat() throws Exception{
            System.out.println ("Animal is eating.");
            throw new Exception();
        }
    }
    
    class Horse extends Animal{
        public void eat() throws IOException{
            System.out.println ("Horse is eating.");
            throw new IOException();
        }
    }
q个例子中,父类抛出了检查异常ExceptionQ子cL出的IOException是Exception的子c,也即是比被重写的Ҏ抛出了更有限的异常,q是可以的。如果反q来Q父cL出IOExceptionQ子cL出更为宽泛的ExceptionQ那么不会通过~译的?br /> 注意Q这U限制只是针Ҏ查异常,至于q行时异常RuntimeException及其子类不再q个限制之中?br />
E、重写规则之五:不能重写被标识ؓfinal的方法?br />
F、重写规则之六:如果一个方法不能被l承Q则不能重写它?br /> 比较典型的就是父cȝprivateҎ。下例会产生一个有的现象?br />     public class Test {
        public static void main (String[] args) {
            //Animal h = new Horse();
            Horse h = new Horse();
            h.eat();
        }
    }

    class Animal {
        private void eat(){
            System.out.println ("Animal is eating.");
        }
    }
    
    class Horse extends Animal{
        public void eat(){
            System.out.println ("Horse is eating.");
        }
    }
q段代码是能通过~译的。表面上看来q反了第六条规则Q但实际上那是一点y合。Animalcȝeat()Ҏ不能被承,因此HorsecM的eat()Ҏ是一个全新的ҎQ不是重写也不是重蝲Q只是一个只属于Horsecȝ全新的方法!q点让很多hqh了,但是也不是那么难以理解?br /> main()Ҏ如果是这P
    Animal h = new Horse();
    //Horse h = new Horse();
    h.eat();
~译器会报错Qؓ什么呢QHorsecȝeat()Ҏ是public的啊Q应该可以调用啊Q请牢记Q多态只看父cd用的ҎQ而不看子cd象的ҎQ?br />

二、方法的重蝲?br /> 重蝲是有好的Q它不要求你在调用一个方法之前{换数据类型,它会自动地寻扑֌配的Ҏ。方法的重蝲是在~译时刻决定调用哪个方法了Q和重写不同。最最常用的地方就是构造器的重载?br />
1、基本数据类型参数的重蝲?br />     public class Test {
        static void method(byte b){
            System.out.println ("method:byte");
        }
        static void method(short s){
            System.out.println ("method:short");
        }
        static void method(int i){
            System.out.println ("method:int");
        }
        static void method(float f){
            System.out.println ("method:float");
        }
        static void method(double d){
            System.out.println ("method:double");
        }
        public static void main (String[] args) {
            method((byte)1);
            method('c');
            method(1);
            method(1L);
            method(1.1);
            method(1.1f);
        }
    }
输出l果Q?br /> method:byte
method:int
method:int
method:float
method:double
method:float

可以看出Q首先要L的是数据cd正好匚wҎ。如果找不到Q那么就提升达能力更强的数据cdQ如上例没有正好容纳long的整数类型,那么p{换ؓfloatcd的。如果通过提升也不能找到合适的兼容cdQ那么编译器׃报错。反正是不会自动转换的数据cd的,必须自己强制转换Q自己来承担转变后果?br />
charcd比较ҎQ如果找不到正好匚w的类型,它会转化为int而不是shortQ虽然char?6位的?br />

2、重载方法的规则?br />
A、被重蝲的方法必L变参数列表?br /> 参数必须不同Q这是最重要的!不同有两个方面,参数的个敎ͼ参数的类型,参数的顺序?br />
B、被重蝲的方法与q回cd无关?br /> 也就是说Q不能通过q回cd来区分重载方法?br />
C、被重蝲的方法可以改变访问修饰符?br /> 没有重写Ҏ那样严格的限制?br />
D、被重蝲的方法可以声明新的或者更q的查异常?br /> 没有重写Ҏ那样严格的限制?br />
E、方法能够在一个类中或者在一个子cM被重载?br />

3、带对象引用参数的方法重载?br />     class Animal {}
    class Horse extends Animal{}
    
    public class Test {
        static void method(Animal a){
            System.out.println ("Animal is called.");
        }
        static void method(Horse h){
            System.out.println ("Horse is called.");
        }
        public static void main (String[] args) {
            Animal a = new Animal();
            Horse h = new Horse();
            Animal ah = new Horse();
            
            method(a);
            method(h);
            method(ah);
        }
    }
输出l果是:
Animal is called.
Horse is called.
Animal is called.
前两个输出没有Q何问题。第三个ҎZ么不是输?#8220;Horse is called.”呢?q是那句老话Q要看引用类型而不是对象类型,Ҏ重蝲是在~译时刻决定的了,引用cd军_了调用哪个版本的重蝲Ҏ?br />

4、重载和重写Ҏ区别的小l?br /> 如果能彻底弄明白下面的例子,说明你对重蝲和重写非怺解了Q可以结束这节的复习了?br />     class Animal {
        public void eat(){
            System.out.println ("Animal is eating.");    
        }
    }
    class Horse extends Animal{
        public void eat(){
            System.out.println ("Horse is eating.");    
        }
        public void eat(String food){
            System.out.println ("Horse is eating " + food);
        }
    }
    
    public class Test {
        public static void main (String[] args) {
            Animal a = new Animal();
            Horse h = new Horse();
            Animal ah = new Horse();
            
            a.eat();
            h.eat();
            h.eat("apple");
            ah.eat();
            //a.eat("apple");
            //ah.eat("apple");
        }
    }

四个输出分别是什么?被注释的两条语句Z么不能通过~译Q?br /> W一条:a.eat(); 普通的Ҏ调用Q没有多态,没什么技术含量。调用了Animalcȝeat()ҎQ输出:Animal is eating.
W二条:h.eat(); 普通的Ҏ调用Q也没什么技术含量。调用了Horsecȝeat()ҎQ输出:Horse is eating.
W三条:h.eat("apple"); 重蝲。Horsecȝ两个eat()Ҏ重蝲。调用了Horsecȝeat(String food)ҎQ输出:Horse is eating apple
W四条:ah.eat(); 多态。前面有例子了,不难理解。输出:Horse is eating.
W五条:a.eat("apple"); 低的错误,AnimalcM没有eat(String food)Ҏ。因此不能通过~译?br /> W六条:ah.eat("apple"); 关键点就在这里。解决的Ҏq是那句老话Q不能看对象cdQ要看引用类型。AnimalcM没有eat(String food)Ҏ。因此不能通过~译?br />
结一下:多态不军_调用哪个重蝲版本Q多态只有在军_哪个重写版本时才起作用?br /> 重蝲对应~译Ӟ重写对应q行时。够z的了吧Q?br />

三、构造方法?br /> 构造方法是一U特D的ҎQ没有构造方法就不能创徏一个新对象。实际上Q不仅要调用对象实际cd的构造方法,q要调用其父cȝ构造方法,向上q溯Q直到ObjectcR构造方法不必显式地调用Q当使用new关键字时Q相应的构造方法会自动被调用?br />
1、构造方法的规则?br /> A、构造方法能使用M讉K修饰W。包括privateQ事实上javacd有很多都是这LQ设计者不希望使用者创cȝ对象?br />
B、构造方法的名称必须与类名相同。这样得构造方法与众不同,如果我们遵守sun的编码规范,g只有构造方法的首字母是大写的?br />
C、构造方法不能有q回cd?br /> 反过来说Q有q回cd的不是构造方?br />     public class Test {
        int Test(){
            return 1;
        }
    }
q个Ҏ是什么东西?一个冒充李늚李鬼而已Qint Test()和其他Q何普通方法没什么两P是普通的ҎQ只不过看v来很恶心Q类似恶心的东西在考试卷子里比较多?br />
D、如果不在类中创q构造方法,~译器会自动生成默认的不带参数的构造函数?br /> q点很容易验证!写一个这L单的c,~译?br /> class Test {
}
对生成的Test.class文g反编译:javap TestQ可以看刎ͼ
D:"JavaCode"bin>javap Test
Compiled from "Test.java"
class Test extends java.lang.Object{
    Test();
}
看到~译器自动添加的默认构造函C吧!

E、如果只创徏了带参数的构造方法,那么~译器不会自动添加无参的构造方法的Q?br />
F、在每个构造方法中Q如果用了重蝲构造函数this()ҎQ或者父cȝ构造方法super()ҎQ那么this()Ҏ或者super()Ҏ必须攑֜W一行。而且q两个方法只能选择一个,因此它们之间没有序问题?br />
G、除了编译器生成的构造方法,而且没有昑ּ地调用super()ҎQ那么编译器会插入一个super()无参调用?br />
H、抽象类有构造方法?br />

四、静态方法的重蝲与重写(覆盖Q?br />
1、静态方法是不能被覆盖的。可以分两种情况讨论Q?br />
A、子cȝ非静态方?#8220;覆盖”父类的静态方法?br /> q种情况下,是不能通过~译的?br />
class Father{
    
static void print(){
        System.out.println (
"in father  method");
    }
}
class Child extends Father{
    
void print(){
        System.out.println (
"in child method");
    }
}

staticҎ表示该方法不兌具体的类的对象,可以通过cd直接调用Q也是~译的前期就l定了,不存在后期动态绑定,也就是不能实现多态。子cȝ非静态方法是与具体的对象l定的,两者有着不同的含义?br />
B、子cȝ静态方?#8220;覆盖”父类静态方法?br /> q个覆盖依然是带引号的。事实上把上面那个例子ChildcȝprintҎ前面加上static修饰W,实能通过~译Q但是不要以是多态!多态的特点是动态绑定,看下面的例子Q?br />
class Father{
    
static void print(){
        System.out.println (
"in father  method");
    }
}
class Child extends Father{
    
static void print(){
        System.out.println (
"in child method");
    }
}

class Test{
    
public static void main (String[] args) {
        Father f 
=new Child();
        f.print();
    }
}

输出l果是:in father  method
从这个结果可以看出,q没有实现多态?br /> 但是q种形式很迷惑hQ貌似多态,实际~程中千万不要这hQ会把大家搞늚Q?br /> 它不W合覆盖表现出来的特性,不应该算是覆盖!
总而言之,静态方法不能被覆盖?br />
2、静态方法可以和非静态方法一栯重蝲?br /> q样的例子太多了Q我不想写例E了。看看javacd中很多这L例子?br /> 如java.util.Arrayscȝ一堆重载的binarySearchҎ?br /> 在这里提一下是因ؓ查资料时看到q样的话“sun的SL275评_静态方法只能控刉态变量(他们本n没有Q,静态方法不能被重蝲和覆?#8230;…”
大家不要怿啊!可以重蝲的。而且静态与非静态方法可以重载?br />
从重载的机制很容易就理解了,重蝲是在~译时刻决定的了,非静态方法都可以Q静态方法怎么可能不会呢?


Eric Gu 2009-06-30 17:17 发表评论
]]>
Java语法ȝ - 字符?/title><link>http://www.aygfsteel.com/EricGu/archive/2009/06/30/284780.html</link><dc:creator>Eric Gu</dc:creator><author>Eric Gu</author><pubDate>Tue, 30 Jun 2009 07:34:00 GMT</pubDate><guid>http://www.aygfsteel.com/EricGu/archive/2009/06/30/284780.html</guid><wfw:comment>http://www.aygfsteel.com/EricGu/comments/284780.html</wfw:comment><comments>http://www.aygfsteel.com/EricGu/archive/2009/06/30/284780.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/EricGu/comments/commentRss/284780.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/EricGu/services/trackbacks/284780.html</trackback:ping><description><![CDATA[Java的String太特别了Q也太常用了Q所以重要。我初学Javap它搞蒙了Q太多؜淆的概念了,比如它的不变性。所以必L入机制地ȝ解它?br /> <br /> <br /> 1、String中的每个字符都是一?6位的Unicode字符Q用Unicode很容易表达丰富的国际化字W集Q比如很好的中文支持。甚至Java的标识符都可以用汉字Q但是没Z用吧Q只在一本清华的《Java2实用教程》看q)?br /> <br /> 2、判断空字符丌Ӏ根据需要自己选择某个或者它们的l合<br />     if ( s == null )    //从引用的角度<br />     if ( s.length() == 0 )     //从长度判?br />     if ( s.trim().length () == 0 )     //是否有多个空白字W?br /> trim()Ҏ的作用是是移除前导和N的Unicode值小?"u0020'的字W,q返?#8220;修剪”好的字符丌Ӏ这U方法很常用Q比如需要用戯入用户名Q用户不心加了前导或者尾部空|一个好的程序应该知道用户不是故意的Q即使是故意的也应该点地处理?br /> 判断IZ是很常用的操作,但是Javacd直到1.6才提供了isEmpty()Ҏ。当且仅?length() ?0 时返?true?br /> <br /> 3、未初始化、空?"与null。它们是不同的概c对未初始化的对象操作会被编译器挡在门外Qnull是一个特D的初始化|是一个不指向M对象的引用,对引用ؓnull的对象操作会在运行时抛出异常NullPointerExceptionQ而空串是长度?的字W串Q和别的字符串的唯一区别是长度??br /> 例子Q?br />     public class StringTest{<br />         static String s1;<br />         public static void main(String[] args) {<br />             String s2;<br />             String s3 = "";<br />             System.out.print(s1.isEmpty());     //q行时异?br />             System.out.print(s2.isEmpty());     //~译出错<br />             System.out.print(s3.isEmpty());     //okQ输出true<br />         }<br />     }<br /> <br /> 4、StringcȝҎ很多Q在~写相关代码的时候看看JDK文档时有好处的,要不然花了大量时间实C个已l存在的Ҏ是很不值得的,因ؓ~写、测试、维护自q代码佉K目的成本增加Q利润减,严重的话会导致开不出工资……<br /> <br /> 5、字W串的比较?br /> Java不允许自定义操作W重载,因此字符串的比较要用compareTo() 或?compareToIgnoreCase()。s1.compareTo(s2)Q返回值大?则,则前者大Q等?Q一般大Q小?Q后者大。比较的依据是字W串中各个字W的Unicode倹{?br /> <br /> 6、toString()Ҏ?br /> Java的Q何对象都有toString()ҎQ是从Object对象l承而来的。它的作用就是让对象在输出时看v来更有意义,而不是奇怪的对象的内存地址。对试也是很有帮助的?br /> <br /> 7、String对象是不变的Q可以变化的是String对象的引用?br /> String name = "ray";<br /> name.concat("long");  //字符串连?br /> System.out.println(name); //输出nameQokQ还?ray"<br /> name = name.concat("long");  //把字W串对象q接的结果赋l了name引用<br /> System.out.println(name);  //输出nameQohQ,变成?raylong"<br /> 上述三条语句其实产生?个String对象Q?ray"Q?long"Q?raylong"。第2条语句确实生了"raylong"字符Ԍ但是没有指定把该字符串的引用赋给谁,因此没有改变name引用。第3条语句根据不变性,q没有改?ray"QJVM创徏了一个新的对象,?ray"Q?long"的连接赋l了name引用Q因此引用变了,但是原对象没变?br /> <br /> 8、String的不变性的机制昄会在String帔R内有大量的冗余。如Q?1" + "2" + "3" +......+ "n" 产生了n+(n+1)个String对象Q因此JavaZ更有效地使用内存QJVM留出一块特D的内存区域Q被UCؓ“String帔R?#8221;。对String多么照顾啊!当编译器遇见String帔R的时候,它检查该池内是否已经存在相同的String帔R。如果找刎ͼ把新常量的引用指向现有的StringQ不创徏M新的String帔R对象?br /> <br /> 那么可能出现多个引用指向同一个String帔RQ会不会有别名的危险呢?No problemQString对象的不变性可以保证不会出现别名问题!q是String对象与普通对象的一点区别?br /> <br /> 乍看hq是底层的机ӞҎ们编E没什么媄响。而且q种机制会大q度提高String的效率,实际上却不是q样。ؓq接n个字W串使用字符串连接操作时Q要消耗的旉是n的^方Q因为每两个字符串连接,它们的内定w要被复制。因此在处理大量的字W串q接Ӟ而且要求性能Ӟ我们不要用StringQStringBuffer是更好的选择?br /> <br /> 8、StringBuffercRStringBuffercL可变的,不会在字W串帔R池中Q而是在堆中,不会留下一大堆无用的对象。而且它可字W串~冲区安全地用于多个U程。每个StringBuffer对象都有一定的定w。只要StringBuffer对象所包含的字W序列的长度没有出此容量,无需分配新的内部~冲区数l。如果内部缓冲区溢出Q则此容量自动增大。这个固定的定w?6个字W。我l这U算法v个名字叫“添饭法”。先l你一满碗饭,不够了再l你一满碗饭?br /> 例子Q?br />     StringBuffer sb = new StringBuffer();    //初始定w?16 个字W?br />     sb.append("1234");    //q是4个字W,那么16个字W的定wp够了Q没有溢?br />     System.out.println(sb.length());    //输出字符串长度是4<br />     System.out.println(sb.capacity());    //输出该字W串~冲区的定w?6<br /> <br />     sb.append("12345678901234567");        //q是17个字W,16个字W的定w不够了,扩容?7+16个字W的定w<br />     System.out.println(sb.length());    //输出字符串长度是17<br />     System.out.println(sb.capacity());    //输出该字W串~冲区的定w?4<br /> <br />     sb.append("890").reverse().insert(10,"-");    <br />     System.out.println(sb);        //输出0987654321-09876543214321<br /> <br /> 字符串的长度和字W缓冲区的容量是两个概念Q注意区别?br /> q有串联的方式看h是不是很P用返回D接v来可以实现这U简z和优雅?br /> <br /> 10、StringBuildercR?从J2SE 5.0 提供了StringBuilderc,它和StringBuffercL孪生兄弟Q很像。它存在的h值在于:对字W串操作的效率更高。不的是线E安全无法保证,不保证同步。那么两者性能到底差多呢Q很多!<br /> 请参阅:http://book.csdn.net/bookfiles/135/1001354628.shtml<br /> 实践Q?br /> 单个U程的时候用StringBuilderc,以提高效率,而且它的API和StringBuffer兼容Q不需要额外的学习成本Q物h廉。多U程时用StringBufferQ以保证安全?br /> <br /> 11、字W串的比较?br /> 下面q条可能会让你晕Q所以你可以选择看或者不看。它不会对你的职业生涯造成M影响。而且谨记一条,比较字符串要用equals()ok了!一旦用?#8220;==”׃出现很怪异的现象。之所以把q部分放在最后,是想节省大家的时_因ؓq条又臭又长。推荐三UhQ一、没事闲着型。二、想深入地理解Java的字W串Q即使明明知道学了也没用。三、和我一L好研I?#8220;?#8221;字有几种写法?br /> <br /> q是那句老话QString太特D了Q以至于某些规则对String不v作用。个人感觉这U特D性ƈ不好。看例子Q?br /> 例子AQ?br />     String str1 = "java";<br />     String str2 = "java";<br />     System.out.print(str1==str2);<br /> 地球上有点Java基础的h都知道会输出falseQ因?=比较的是引用Qequals比较的是内容。不是我忽悠大家Q你们可以在自己的机子上q行一下,l果是trueQ原因很单,String对象被放q常量池里了Q再ơ出?#8220;java”字符串的时候,JVM很兴奋地把str2的引用也指向?#8220;java”对象Q它认ؓ自己节省了内存开销。不隄解吧 呵呵<br /> 例子BQ?br />     String str1 = new String("java");<br />     String str2 = new String("java");<br />     System.out.print(str1==str2);<br /> 看过上例的都学聪明了Q这ơ肯定会输出trueQ很不幸QJVMq没有这么做Q结果是false。原因很单,例子A中那U声明的方式实是在String帔R池创?#8220;java”对象Q但是一旦看到new关键字,JVM会在堆中为String分配I间。两者声明方式貌合神,q也是我?#8220;如何创徏字符串对?#8221;攑ֈ后面来讲的原因。大家要沉住气,q有一个例子?br /> 例子CQ?br />     String str1 = "java";<br />     String str2 = "blog";<br />     String s = str1+str2;<br />     System.out.print(s=="javablog");<br /> 再看q个例子Q很多同志不敢妄a是trueq是false了吧。爱玩脑{急{弯的Z说是false?#8230;…恭喜你,你会抢答了!把那?#8220;?#8221;字去掉你完全正。原因很单,JVM实会对型如String str1 = "java"; 的String对象攑֜字符串常量池里,但是它是在编译时刻那么做的,而String s = str1+str2; 是在q行时刻才能知道Q我们当然一眼就看穿了,可是Java必须在运行时才知道的Qh脑和电脑的结构不同)Q也是说str1+str2是在堆里创徏的,s引用当然不可能指向字W串帔R池里的对象。没崩溃的hl箋看例子D?br /> 例子DQ?br />     String s1 = "java";<br />     String s2 = new String("java");<br />     System.out.print(s1.intern()==s2.intern());<br /> intern()是什么东东?反正l果是true。如果没用过q个ҎQ而且训练有素的程序员会去看JDK文档了。简单点说就是用intern()Ҏ可以用“==”比较字符串的内容了。在我看到intern()Ҏ到底有什么用之前Q我认ؓ它太多余了。其实我写的q一条也很多余,intern()Ҏq存在诸多的问题Q如效率、实C的不l一……<br /> 例子EQ?br />     String str1 = "java";<br />     String str2 = new String("java");<br />     System.out.print(str1.equals(str2));<br /> 无论在常量池q是堆中的对象,用equals()Ҏ比较的就是内容,p么简单!看完此条的h一定很后悔Q但是在开始我劝你别看?#8230;…<br /> <br /> 后记Q用彪哥的话?#8220;有意思吗Q?#8221;Q确实没劌Ӏ在写这D늚时候我也是思量再三Q感觉自己像孔乙q耀“?#8221;字有几种写法。我查了一下茴 Q回Q囘Q囬Q还有一U是“?#8221;字里面有?#8220;?#8221;字,后面q四个都加上草字?#8230;…<br /> <img src ="http://www.aygfsteel.com/EricGu/aggbug/284780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/EricGu/" target="_blank">Eric Gu</a> 2009-06-30 15:34 <a href="http://www.aygfsteel.com/EricGu/archive/2009/06/30/284780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FreeMarker设计指南(完整整理)http://www.aygfsteel.com/EricGu/archive/2009/06/18/282974.htmlEric GuEric GuThu, 18 Jun 2009 01:19:00 GMThttp://www.aygfsteel.com/EricGu/archive/2009/06/18/282974.htmlhttp://www.aygfsteel.com/EricGu/comments/282974.htmlhttp://www.aygfsteel.com/EricGu/archive/2009/06/18/282974.html#Feedback0http://www.aygfsteel.com/EricGu/comments/commentRss/282974.htmlhttp://www.aygfsteel.com/EricGu/services/trackbacks/282974.html快速入?

Q?Q模?+ 数据模型 = 输出

FreeMarkerZ设计者和E序员是h不同专业技能的不同个体的观念他们是分工力_的:
设计者专注于表示——创建HTML文g、图片、Web面的其它可视化斚wQ?br /> E序员创建系l,生成设计面要显C的数据?br /> l常会遇到的问题是:在Web面Q或其它cd的文档)中显C的信息在设计页面时是无效的Q是Z动态数据的。在q里Q你可以在HTMLQ或其它要输出的文本Q中加入一些特定指令,FreeMarker会在输出面l最l用hQ用适当的数据替代这些代码?/p>

先来解释一下freemaker的基本语法了Q?br /> <# ... > 中存放所有freemaker的内容,之外的内容全部原栯出?br /> <@ ... /> 是函数调?br /> 两个定界W内的内容中Q第一个符可C指令或者函数名Q其后的跟随参数。freemaker提供的控制包括如下:
<#if condition><#elseif condition><#else> 条g判断
<#list hash_or_seq as var> 遍历hash表或者collectionQfreemakerUCsequenceQ的成员
<#macro name param1 param2 ... ><#nested param> 宏,无返回参?br /> <#function name param1 param2><#return val>函数Q有q回参数
var?member_function(...) 用函数对varq行转换QfreemakerUCؓbuild-ins。实际内部实现类似member_function(var, ...)
stringA[M .. N] 取子字符ԌcMsubstring(stringA, M, N)
{key:value, key2:value2 ...} 直接定义一个hash?br /> [item0, item1, item2 ...] 直接定义一个序?br /> hash0[key0] 存取hash表中key对应的元?br /> seq0[5] 存取序列指定下标的元?br /> <@function1 param0 param1 ... /> 调用函数function1
<@macro0 param0 param1 ; nest_param0 nest_param1 ...> nest_body <
/@macro> 调用宏,q处理宏的嵌?br /> <#assign var = value > 定义变量q初始化
<#local var = value> ?macro 或?function 中定义局部变量ƈ初始?br /> <#global var = value > 定义全局变量q初始化
${var} 输出q替换ؓ表达式的?br /> <#visit xmlnode> 调用macro匚wxmlnode本n及其子节?br /> <#recurse xmlnode> 调用macro匚wxmlnode的子节点


下面是一个例子:

<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
<a href="${latestProduct.url}">${latestProduct.name}</a>!
</body>
</html>
q个例子是在单的HTML中加入了一些由${…}包围的特定代码,q些特定代码是FreeMarker的指令,而包含FreeMarker的指令的文gq为模板(TemplateQ?br /> 至于user、latestProduct.url和latestProduct.name来自于数据模型(data modelQ?br /> 数据模型q序员~程来创建,向模板提供变化的信息Q这些信息来自于数据库、文Ӟ甚至于在E序中直接生成?br /> 模板设计者不兛_数据从那儿来Q只知道使用已经建立的数据模型?br />

下面是一个可能的数据模型Q?

(root)
|
+- user = "Big Joe"
|
+- latestProduct
|
+- url = "products/greenmouse.html"
|
+- name = "green mouse"
数据模型cM于计机的文件系l,latestProduct可以看作是目录?

2、数据模?

Q?Q基

在快速入门中介绍了在模板中用的三种基本对象cdQscalars、hashes 和sequencesQ其实还可以有其它更多的能力Q?

  • scalarsQ存储单?
  • hashesQ充当其它对象的容器Q每个都兌一个唯一的查询名?
  • sequencesQ充当其它对象的容器Q按ơ序讉K
  • ҎQ通过传递的参数q行计算Q以新对象返回结?
  • 用户自定义FTL标记Q宏和变换器

通常每个变量只具有上q的一U能力,但一个变量可以具有多个上q能力,如下面的例子Q?

(root)
|
+- mouse = "Yerri"
|
+- age = 12
|
+- color = "brown">
mouse既是scalars又是hashesQ将上面的数据模型合q到下面的模板:
${mouse}       <#-- use mouse as scalar -->
${mouse.age} <#-- use mouse as hash -->
${mouse.color} <#-- use mouse as hash -->
输出l果是:
Yerri
12
brown

Q?QScalar变量

Scalar变量存储单|可以是:

  • 字符Ԍ单文本,在模板中使用引号Q单引号或双引号Q括?
  • 数字Q在模板中直接用数字?
  • 日期Q存储日?旉相关的数据,可以是日期、时间或日期-旉QTimestampQ;通常情况Q日期值由E序员加到数据模型中Q设计者只需要显C它?
  • 布尔|true或falseQ通常?lt;#if …>标记中?

Q?Qhashes 、sequences和集?

有些变量不包含Q何可昄的内容,而是作ؓ容器包含其它变量Q者有两种cdQ?

  • hashesQ具有一个唯一的查询名字和它包含的每个变量相关?
  • sequencesQ用数字和它包含的每个变量相关联,索引g0开?

集合变量通常cMsequencesQ除非无法访问它的大和不能使用索引来获得它的子变量Q集合可以看作只能由<#list …>指o使用的受限sequences

Q?Q方?

Ҏ变量通常是基于给出的参数计算倹{?

下面的例子假讄序员已经方法变量avg攑ֈ数据模型中,用来计算数字q_|

The average of 3 and 5 is: ${avg(3, 5)}
The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}
The average of the price of python and elephant is:
${avg(animals.python.price, animals.elephant.price)}

Q?Q宏和变换器

宏和变换器变量是用户自定义指令(自定义FTL标记Q,会在后面讲述q些高Ҏ?

Q?Q节?

节点变量表示为树型结构中的一个节点,通常在XML处理中用,会在后面的专门章节中?

3、模?

Q?Q整体结?

模板使用FTLQFreeMarker模板语言Q编写,是下面各部分的一个组合:

  • 文本Q直接输?
  • InterpolationQ由${和}Q或#{和}来限定,计算值替代输?
  • FTL标记QFreeMarker指oQ和HTML标记cMQ名字前?予以区分Q不会输?
  • 注释Q由<#--?->限定Q不会输?

下面是以一个具体模板例子:

<html>
<head>
<title>Welcome!</title>
</head>
<body>
<#-- Greet the user with his/her name -->
<h1>Welcome ${user}!</h1>
<p>We have these animals:
<ul>
<#list animals as being>
<li>${being.name} for ${being.price} Euros
</#list>
</ul>
</body>
</html>

注意事项Q?

  • FTL区分大小写,所以list是正的FTL指oQ而List不是Q?{name}?{NAME}是不同的
  • Interpolation只能在文本中使用
  • FTL标记不能位于另一个FTL标记内部Q例如:
<#if <#include 'foo'>='bar'>...</if>
  • 注释可以位于FTL标记和Interpolation内部Q如下面的例子:
<h1>Welcome ${user <#-- The name of user -->}!</h1>
<p>We have these animals:
<ul>
<#list <#-- some comment... --> animals as <#-- again... --> being>
...
  • 余的I白字符会在模板输出时移?

Q?Q指?

在FreeMarker中,使用FTL标记引用指o。有三种FTL标记Q这和HTML标记是类似的Q?

  • 开始标讎ͼ<#directivename parameters>
  • l束标记Q?lt;/#directivename>
  • I内Ҏ令标讎ͼ<#directivename parameters/>

有两U类型的指oQ预定义指o和用户定义指令?

用户定义指o要用@替换#Q如<@mydirective>...</@mydirective>Q会在后面讲qͼ?

FTL标记不能够交叉,而应该正的嵌套Q如下面的代码是错误的:

<ul>
<#list animals as being>
<li>${being.name} for ${being.price} Euros
<#if use = "Big Joe">
(except for you)
</#list>
</#if> <#-- WRONG! -->
</ul>
如果使用不存在的指oQFreeMarker不会使用模板输出Q而是产生一个错误消息?

FreeMarker会忽略FTL标记中的I白字符Q如下面的例子:

<#list
animals as
being
>
${being.name} for ${being.price} Euros
</#list >
但是Q?lt;?lt;/和指令之间不允许有空白字W?

Q?Q表辑ּ

直接指定?/strong>

  • 字符?
使用单引h双引号限?

如果包含Ҏ字符需要{义,如下面的例子Q?

${"It's \"quoted\" and
this is a backslash: \\"}

${'It\'s "quoted" and
this is a backslash: \\'}
输出l果是:
It's "quoted" and
this is a backslash: \

It's "quoted" and
this is a backslash: \
下面是支持的转义序列Q?
转义序列 含义
\" 双引?u0022)
\' 单引?u0027)

反斜?u005C)
\n 换行(u000A)
\r Return (u000D)
\t Tab (u0009)
\b Backspace (u0008)
\f Form feed (u000C)
\l <
\g >
\a &
\{ {
\xCode 4?6q制Unicode代码

有一cȝD的字符串称为raw字符Ԍ被认为是U文本,其中的\和{{不hҎ含义Q该cdW串在引号前面加rQ下面是一个例子:

${r"${foo}"}

${r"C:\foo\bar"}
输出的结果是Q?
${foo}

C:\foo\bar
  • 数字

直接输入Q不需要引?

_ֺ数字使用“.”分隔Q不能用分l符?

目前版本不支持科学计数法Q所?#8220;1E3”是错误的

不能省略数点前面的0Q所?#8220;.5”是错误的

数字8?8?8?.00都是相同?

  • 布尔?

true和falseQ不使用引号

  • 序列

由逗号分隔的子变量列表Q由Ҏ号限定,下面是一个例子:

<#list ["winter", "spring", "summer", "autumn"] as x>
${x}
</#list>
输出的结果是Q?
winter
spring
summer
autumn
列表的项目是表达式,所以可以有下面的例子:
[2 + 2, [1, 2, 3, 4], "whatnot"]
可以使用数字范围定义数字序列Q例?..5{同于[2, 3, 4, 5]Q但是更有效率,注意数字范围没有Ҏ?

可以定义反递增的数字范_?..2

  • 散列QhashQ?
由逗号分隔的键/值列表,由大括号限定Q键和g间用冒号分隔Q下面是一个例子:
{"name":"green mouse", "price":150}
键和值都是表辑ּQ但是键必须是字W串

获取变量

  • 层变量Q?${variable}Q变量名只能是字母、数字、下划线?、@?的组合,且不能以数字开?
  • 从散列中获取数据

可以使用点语法或Ҏ可法,假设有下面的数据模型Q?

(root)
|
+- book
| |
| +- title = "Breeding green mouses"
| |
| +- author
| |
| +- name = "Julia Smith"
| |
| +- info = "Biologist, 1923-1985, Canada"
|
+- test = "title"
下面都是{h的:
book.author.name
book["author"].name
book.author.["name"]
book["author"]["name"]
使用点语法,变量名字有顶层变量一L限制Q但Ҏ可法没有该限制Q因为名字是L表达式的l果
  • 从序列获得数据:和散列的Ҏ可法语法一P只是Ҏ号中的表辑ּ值必L数字Q注意:W一个项目的索引?

序列片断Q用[startIndex..endIndex]语法Q从序列中获得序列片断(也是序列Q;startIndex和endIndex是结果ؓ数字的表辑ּ

  • Ҏ变量QFreeMarker内定义变量,使用.variablename语法讉K

字符串操?

  • InterpolationQ或q接操作Q?

可以使用${..}Q或#{..}Q在文本部分插入表达式的|例如Q?

${"Hello ${user}!"}

${"${user}${user}${user}${user}"}
可以使用+操作W获得同Ll果
${"Hello " + user + "!"}

${user + user + user + user}
${..}只能用于文本部分Q下面的代码是错误的Q?
<#if ${isBig}>Wow!</#if>

<#if "${isBig}">Wow!</#if>
应该写成Q?
<#if isBig>Wow!</#if>
  • 子串

例子Q假设user的gؓ“Big Joe”Q:

${user[0]}${user[4]}

${user[1..4]}
l果是(注意W一个字W的索引?Q:
BJ

ig J
序列操作
  • q接操作Q和字符串一P使用+Q下面是一个例子:
<#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>
- ${user}
</#list>
输出l果是:
- Joe
- Fred
- Julia
- Kate
散列操作
  • q接操作Q和字符串一P使用+Q如果具有相同的keyQ右边的值替代左边的|例如Q?
<#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>
- Joe is ${ages.Joe}
- Fred is ${ages.Fred}
- Julia is ${ages.Julia}
输出l果是:
- Joe is 30
- Fred is 25
- Julia is 18
术q算
  • Q、-?#215;、/、%Q下面是一个例子:
${x * x - 100}
${x / 2}
${12 % 10}
输出l果是(假设x?Q:
-75
2.5
2
操作W两边必L数字Q因此下面的代码是错误的Q?
${3 * "5"} <#-- WRONG! -->  
使用+操作W时Q如果一Ҏ数字Q一Ҏ字符Ԍ׃自动数字{换ؓ字符Ԍ例如Q?
${3 + "5"}  
输出l果是:
35
使用内徏的intQ后面讲qͼ获得整数部分Q例如:
${(x/2)?int}
${1.1?int}
${1.999?int}
${-1.1?int}
${-1.999?int}
输出l果是(假设x?Q:
2
1
1
-1
-1
  • 比较操作W?

使用=Q或==Q完全相{)试两个值是否相{,使用!= 试两个值是否不相等

=?=两边必须是相同类型的|否则会生错误,例如<#if 1 = "1">会引起错?

Freemarker是精比较,所以对"x"?x "?X"是不相等?

Ҏ字和日期可以使用<?lt;=?gt;?gt;=Q但不能用于字符?

׃Freemarker会将>解释成FTL标记的结束字W,所以对?gt;?gt;=可以使用括号来避免这U情况,例如<#if (x > y)>

另一U替代的Ҏ是,使用lt、lte、gt和gte来替?lt;?lt;=?gt;?gt;=

  • 逻辑操作W?

&&QandQ、||QorQ?QnotQ,只能用于布尔|否则会生错?

例子Q?

<#if x < 12 && color = "green">
We have less than 12 things, and they are green.
</#if>
<#if !hot> <#-- here hot must be a boolean -->
It's not hot.
</#if>
  • 内徏函数

内徏函数的用法类D问散列的子变量,只是使用“?”替代“.”Q下面列出常用的一些函?

    • 字符串用的Q?

htmlQ对字符串进行HTML~码

cap_firstQ字符串第一个字母大?

lower_caseQ将字符串{换成写

upper_caseQ将字符串{换成大写

trimQ去掉字W串前后的空白字W?

    • 序列使用的:

sizeQ获得序列中元素的数?

    • 数字使用的:

intQ取得数字的整数部分Q如-1.9?int的结果是-1Q?

例子Q假设test保存字符?Tom & Jerry"Q:

${test?html}
${test?upper_case?html}
输出l果是:
Tom &amp; Jerry
TOM &amp; JERRY
  • 操作W优先顺?
操作W组 操作W?
后缀 [subvarName] [subStringRange] . (methodParams)
一? +expr?expr?
内徏 ?
乘法 *?/ ?
加法 +?
关系 <?gt;?lt;=?gt;=Qlt、lte、gt、gteQ?
相等 ==Q?Q?=
逻辑and &&
逻辑or 双竖U?/td>
数字范围 ..

Q?QInterpolation

Interpolation有两U类型:

  1. 通用InterpolationQ?{expr}
  1. 数字InterpolationQ?{expr}?{expr; format}

注意QInterpolation只能用于文本部分

  • 通用Interpolation

插入字符串|直接输出表达式结?

插入数字|Ҏ~省格式Q由#setting指o讄Q将表达式结果{换成文本输出Q可以用内建函数string格式化单个InterpolationQ下面是一个例子:

<#setting number_format="currency"/>
<#assign answer=42/>
${answer}
${answer?string} <#-- the same as ${answer} -->
${answer?string.number}
${answer?string.currency}
${answer?string.percent}
输出l果是:
$42.00
$42.00
42
$42.00
4,200%
插入日期|Ҏ~省格式Q由#setting指o讄Q将表达式结果{换成文本输出Q可以用内建函数string格式化单个InterpolationQ下面是一个用格式模式的例子Q?
${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}
${lastUpdated?string("EEE, MMM d, ''yy")}
${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}
输出的结果类g面的格式Q?
2003-04-08 21:24:44 Pacific Daylight Time
Tue, Apr 8, '03
Tuesday, April 08, 2003, 09:24:44 PM (PDT)
插入布尔|Ҏ~省格式Q由#setting指o讄Q将表达式结果{换成文本输出Q可以用内建函数string格式化单个InterpolationQ下面是一个例子:
<#assign foo=true/>
${foo?string("yes", "no")}
输出l果是:
yes
  • 数字Interpolation?{expr; format}形式可以用来格式化数字,format可以是:

mXQ小数部分最X?

MXQ小数部分最大X?

例子Q?

<#-- If the language is US English the output is: -->
<#assign x=2.582/>
<#assign y=4/>
#{x; M2} <#-- 2.58 -->
#{y; M2} <#-- 4 -->
#{x; m1} <#-- 2.6 -->
#{y; m1} <#-- 4.0 -->
#{x; m1M2} <#-- 2.58 -->
#{y; m1M2} <#-- 4.0 -->

4、杂?

Q?Q用户定义指?

宏和变换器变量是两种不同cd的用户定义指令,它们之间的区别是宏是在模板中使用macro指o定义Q而变换器是在模板外由E序定义Q这里只介绍?

  • 基本用法

宏是和某个变量关联的模板片断Q以便在模板中通过用户定义指o使用该变量,下面是一个例子:

<#macro greet>
<font size="+2">Hello Joe!</font>
</#macro>
作ؓ用户定义指o使用宏变量时Q用@替代FTL标记中的#
<@greet></@greet>
如果没有体内容,也可以用:
<@greet/>
  • 参数

在macro指o中可以在宏变量之后定义参敎ͼ如:

<#macro greet person>
<font size="+2">Hello ${person}!</font>
</#macro>
可以q样使用q个宏变量:
<@greet person="Fred"/> and <@greet person="Batman"/> 
输出l果是:
  <font size="+2">Hello Fred!</font>

and <font size="+2">Hello Batman!</font>

宏的参数是FTL表达式,所以下面的代码h不同的意思:

<@greet person=Fred/>
q意味着Fred变量的glperson参数Q该g仅是字符Ԍq可以是其它cdQ甚x复杂的表辑ּ

可以有多参数Q下面是一个例子:

<#macro greet person color>
<font size="+2" color="${color}">Hello ${person}!</font>
</#macro>
可以q样使用该宏变量Q?
<@greet person="Fred" color="black"/> 
其中参数的次序是无关的,因此下面是等LQ?
<@greet color="black" person="Fred"/>
只能使用在macro指o中定义的参数Qƈ且对所有参数赋|所以下面的代码是错误的Q?
<@greet person="Fred" color="black" background="green"/>
<@greet person="Fred"/>
可以在定义参数时指定~省|如:
<#macro greet person color="black">
<font size="+2" color="${color}">Hello ${person}!</font>
</#macro>
q样<@greet person="Fred"/>正了

宏的参数是局部变量,只能在宏定义中有?

  • 嵌套内容

用户定义指o可以有嵌套内容,使用<#nested>指o执行指o开始和l束标记之间的模板片?

例子Q?

<#macro border>
<table border=4 cellspacing=0 cellpadding=4><tr><td>
<#nested>
</tr></td></table>
</#macro>
q样使用该宏变量Q?
<@border>The bordered text</@border>
输出l果Q?
  <table border=4 cellspacing=0 cellpadding=4><tr><td>
The bordered text
</tr></td></table>

<#nested>指o可以被多ơ调用,例如Q?

<#macro do_thrice>
<#nested>
<#nested>
<#nested>
</#macro>
<@do_thrice>
Anything.
</@do_thrice>
输出l果Q?
  Anything.
Anything.
Anything.
嵌套内容可以是有效的FTLQ下面是一个有些复杂的例子Q?<@border> <ul> <@do_thrice> <li><@greet person="Joe"/> </@do_thrice> </ul> </@border> }}} 输出l果Q?
  <table border=4 cellspacing=0 cellpadding=4><tr><td>
<ul>
<li><font size="+2">Hello Joe!</font>
<li><font size="+2">Hello Joe!</font>
<li><font size="+2">Hello Joe!</font>
</ul>
</tr></td></table>
宏定义中的局部变量对嵌套内容是不可见的,例如Q?
<#macro repeat count>
<#local y = "test">
<#list 1..count as x>
${y} ${count}/${x}: <#nested>
</#list>
</#macro>
<@repeat count=3>${y?default("?")} ${x?default("?")} ${count?default("?")}</@repeat>
输出l果Q?
    test 3/1: ? ? ?
test 3/2: ? ? ?
test 3/3: ? ? ?
  • 在宏定义中用@环变?

用户定义指o可以有@环变量,通常用于重复嵌套内容Q基本用法是Q作为nested指o的参C递@环变量的实际|而在调用用户定义指oӞ?lt;@…>开始标记的参数后面指定循环变量的名?

例子Q?

<#macro repeat count>
<#list 1..count as x>
<#nested x, x/2, x==count>
</#list>
</#macro>
<@repeat count=4 ; c, halfc, last>
${c}. ${halfc}<#if last> Last!</#if>
</@repeat>
输出l果Q?
  1. 0.5
2. 1
3. 1.5
4. 2 Last!

指定的@环变量的数目和用户定义指令开始标记指定的不同不会有问?

调用时少指定循环变量Q则多指定的g可见

调用时多指定循环变量Q多余的循环变量不会被创?

Q?Q在模板中定义变?

在模板中定义的变量有三种cdQ?

  • plain变量Q可以在模板的Q何地方访问,包括使用include指o插入的模板,使用assign指o创徏和替?
  • 局部变量:在宏定义体中有效Q用local指o创徏和替?
  • 循环变量Q只能存在于指o的嵌套内容,由指令(如listQ自动创?

宏的参数是局部变量,而不是@环变量;局部变量隐藏(而不是覆盖)同名的plain变量Q@环变量隐藏同名的局部变量和plain变量Q下面是一个例子:

<#assign x = "plain">
1. ${x} <#-- we see the plain var. here -->
<@test/>
6. ${x} <#-- the value of plain var. was not changed -->
<#list ["loop"] as x>
7. ${x} <#-- now the loop var. hides the plain var. -->
<#assign x = "plain2"> <#-- replace the plain var, hiding does not mater here -->
8. ${x} <#-- it still hides the plain var. -->
</#list>
9. ${x} <#-- the new value of plain var. -->
<#macro test>
2. ${x} <#-- we still see the plain var. here -->
<#local x = "local">
3. ${x} <#-- now the local var. hides it -->
<#list ["loop"] as x>
4. ${x} <#-- now the loop var. hides the local var. -->
</#list>
5. ${x} <#-- now we see the local var. again -->
</#macro>
输出l果Q?
1. plain
2. plain
3. local
4. loop
5. local
6. plain
7. loop
8. loop
9. plain2

内部循环变量隐藏同名的外部@环变量,如:

<#list ["loop 1"] as x>
${x}
<#list ["loop 2"] as x>
${x}
<#list ["loop 3"] as x>
${x}
</#list>
${x}
</#list>
${x}
</#list>
输出l果Q?
  loop 1
loop 2
loop 3
loop 2
loop 1
模板中的变量会隐藏(而不是覆盖)数据模型中同名变量,如果需要访问数据模型中的同名变量,使用Ҏ变量globalQ下面的例子假设数据模型中的user的值是Big JoeQ?
<#assign user = "Joe Hider">
${user} <#-- prints: Joe Hider -->
${.globals.user} <#-- prints: Big Joe -->

Q?Q名字空?

通常情况Q只使用一个名字空_UCؓd字空?

Z创徏可重用的宏、变换器或其它变量的集合Q通常U库Q,必须使用多名字空_其目的是防止同名冲突

  • 创徏?

下面是一个创建库的例子(假设保存在lib/my_test.ftl中)Q?

<#macro copyright date>
<p>Copyright (C) ${date} Julia Smith. All rights reserved.
<br>Email: ${mail}</p>
</#macro>
<#assign mail = "jsmith@acme.com">
使用import指o导入库到模板中,Freemarker会ؓ导入的库创徏新的名字I间Qƈ可以通过import指o中指定的散列变量讉K库中的变量:
<#import "/lib/my_test.ftl" as my>
<#assign mail="fred@acme.com">
<@my.copyright date="1999-2002"/>
${my.mail}
${mail}
输出l果Q?
  <p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.
<br>Email: jsmith@acme.com</p>
jsmith@acme.com
fred@acme.com
可以看到例子中用的两个同名变量q没有冲H,因ؓ它们位于不同的名字空?

可以使用assign指o在导入的名字I间中创建或替代变量Q下面是一个例子:

<#import "/lib/my_test.ftl" as my>
${my.mail}
<#assign mail="jsmith@other.com" in my>
${my.mail}
输出l果Q?
jsmith@acme.com
jsmith@other.com
数据模型中的变量M地方都可见,也包括不同的名字I间Q下面是修改的库Q?
<#macro copyright date>
<p>Copyright (C) ${date} ${user}. All rights reserved.</p>
</#macro>
<#assign mail = "${user}@acme.com">
假设数据模型中的user变量的值是FredQ则下面的代码:
<#import "/lib/my_test.ftl" as my>
<@my.copyright date="1999-2002"/>
${my.mail}
输出l果Q?
  <p>Copyright (C) 1999-2002 Fred. All rights reserved.</p>
Fred@acme.com


补充Q静态方法的调用Q:


Ҏ1Q?/strong>
##定义配置文g freemarkerstatic.properties
_Validator=com.longyou.util.Validator
_Functions=com.longyou.util.Functions
_EscapeUtils=com.longyou.util.EscapeUtils
/调用代码
${_Functions.toUpperCase("Hello")}<br>
${_EscapeUtils.escape("狼的原野")}

Ҏ2Q?/strong>
${stack.findValue("@package.ClassName@method")}


补充Q常用语?/strong>

EG.一个对象BOOK

1.输出 ${book.name}

I值判断:${book.name?if_exists },

${book.name?default(‘xxx’)}//默认值xxx

${ book.name!"xxx"}//默认值xxx

日期格式Q?{book.date?string('yyyy-MM-dd')}

数字格式Q?{book?string.number}--20

${book?string.currency}--<#-- $20.00 -->

${book?string.percent}?lt;#-- 20% -->

插入布尔|

<#assign foo=ture />

${foo?string("yes","no")} <#-- yes -->

 

 

 

 

2Q逻辑判断

a:

<#if condition>...

<#elseif condition2>...

<#elseif condition3>......

<#else>...

其中I值判断可以写?lt;#if book.name?? >

 

b:

<#switch value>

<#case refValue1>

...

<#break>

<#case refValue2>

...

<#break>

...

<#case refValueN>

...

<#break>

<#default>

...

 

3Q@环读?/p>

<#list sequence as item>

...

I值判?lt;#if bookList?size = 0>

e.g.

<#list employees as e>

${e_index}. ${e.name}

输出:

1. Readonly

2. Robbin


freemarker中Map的?/strong>
<#list testMap?keys as testKey>
       < option value="${testKey}" >
              ${testMap[testKey]}
     </option>
<
/#list>

freemarker的Eclipse插g
  • If you use Eclipse 2.x:
    1. Open the Window menu, then Open Perspective -> Install/Update
    2. Click with the right mouse button on the Feature Updates view, then select New -> Site Bookmark
    3. In the displayed dialog box, type "FreeMarker" for Name and "http://www.freemarker.org/eclipse/update" for URL. Leave the "Bookmark type" radio buttons on "Eclipse update site".
    4. Click Finish
    5. Open the tree node under the newly created update site named "FreeMarker", select the "FreeMarker X.Y.Z" feature, and install it using the Install now button in the preview pane.
  • If you use Eclipse 3.x:
    1. Help -> Software updates -> Find and install....
    2. Choose "Search for new features to install".
    3. Click Add Update Site..., and type "FreeMarker" for Name and "http://www.freemarker.org/eclipse/update" for URL.
    4. Check the box of the "FreeMarker" feature.
    5. "Next"-s until it is installed...


Eric Gu 2009-06-18 09:19 发表评论
]]>
J2SE5中的最新注释功能SuppressWarnings http://www.aygfsteel.com/EricGu/archive/2009/06/16/282626.htmlEric GuEric GuTue, 16 Jun 2009 08:02:00 GMThttp://www.aygfsteel.com/EricGu/archive/2009/06/16/282626.htmlhttp://www.aygfsteel.com/EricGu/comments/282626.htmlhttp://www.aygfsteel.com/EricGu/archive/2009/06/16/282626.html#Feedback0http://www.aygfsteel.com/EricGu/comments/commentRss/282626.htmlhttp://www.aygfsteel.com/EricGu/services/trackbacks/282626.html阅读全文

Eric Gu 2009-06-16 16:02 发表评论
]]>
IntelliJ Idea 常用快捷键列?/title><link>http://www.aygfsteel.com/EricGu/archive/2009/03/26/262020.html</link><dc:creator>Eric Gu</dc:creator><author>Eric Gu</author><pubDate>Thu, 26 Mar 2009 01:35:00 GMT</pubDate><guid>http://www.aygfsteel.com/EricGu/archive/2009/03/26/262020.html</guid><wfw:comment>http://www.aygfsteel.com/EricGu/comments/262020.html</wfw:comment><comments>http://www.aygfsteel.com/EricGu/archive/2009/03/26/262020.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/EricGu/comments/commentRss/262020.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/EricGu/services/trackbacks/262020.html</trackback:ping><description><![CDATA[<p>Alt+回R 导入?自动修正<span style="display: none"> Y#a 5Q;%C </span> <br /> Ctrl+N  查找c?span style="display: none"> }8dN-@% </span> <br /> Ctrl+Shift+N 查找文g<span style="display: none"> \$:/ad </span> <br /> Ctrl+Alt+L  格式化代?span style="display: none"> ^vz>q?)N </span> <br /> Ctrl+Alt+O 优化导入的类和包<span style="display: none"> d B)QPI$ </span> <br /> Alt+Insert 生成代码(如get,setҎ,构造函数等)<span style="display: none"> 8 A,,7dI </span> <br /> Ctrl+E或者Alt+Shift+C  最q更改的代码<span style="display: none"> {dS(}X&qw- </span> <br /> Ctrl+R 替换文本<span style="display: none"> m[NkF4K` </span> <br /> Ctrl+F 查找文本<span style="display: none"> nRgAKNV ) </span> <br /> Ctrl+Shift+Space 自动补全代码<span style="display: none"> ',+6'2ex </span> <br /> Ctrl+I格 代码提示<span style="display: none"> k-1Xx>g </span> <br /> Ctrl+Alt+Space cd或接口名提示<span style="display: none"> vgX;@  </span> <br /> Ctrl+P Ҏ参数提示<span style="display: none"> V#" )7P </span> <br /> Ctrl+Shift+Alt+N 查找cM的方法或变量<span style="display: none"> =1ov </span> <br /> Alt+Shift+C Ҏ最q修改的代码<span style="display: none"> r?PrlqOM </span> <br /> <span style="display: none"> B[+:q]7 </span> <br /> Shift+F6  重构-重命?span style="display: none"> H["Jg)kJ </span> <br /> Ctrl+Shift+先上?span style="display: none"> ==ko,FJSV </span> <br /> Ctrl+X 删除?span style="display: none"> rL 2+5| </span> <br /> Ctrl+D 复制?span style="display: none"> gJmr $ </span> <br /> Ctrl+/ ?Ctrl+Shift+/  注释Q?/ 或?*...*/ Q?span style="display: none"> hrkkRl </span> <br /> Ctrl+J  自动代码<span style="display: none"> i*+'FH </span> <br /> Ctrl+E 最q打开的文?span style="display: none"> TM~yQ6K </span> <br /> Ctrl+H 昄cȝ构图<span style="display: none"> 7OE|# </span> <br /> Ctrl+Q 昄注释文档<span style="display: none"> (LlsVoL2 </span> <br /> Alt+F1 查找代码所在位|?span style="display: none"> Fv}![ 7| </span> <br /> Alt+1 快速打开或隐藏工E面?span style="display: none"> ]N='WJ(8/ </span> <br /> Ctrl+Alt+ left/right q回至上ơ浏览的位置<span style="display: none"> A[b.}3%f </span> <br /> Alt+ left/right 切换代码视图<span style="display: none"> XnN*gM l! </span> <br /> Alt+ Up/Down 在方法间快速移动定?span style="display: none"> ^N=<b0rq </span> <br /> Ctrl+Shift+Up/Down 代码向上/下移动?span style="display: none"> m4$mF/-Ny+ </span> <br /> F2 或Shift+F2 高亮错误或警告快速定?span style="display: none"> %}V4b </span> <br /> <span style="display: none">wsPWQvT </span> <br /> 代码标签输入完成后,按TabQ生成代码?span style="display: none"> &3"n7 fmT </span> <br /> 选中文本Q按Ctrl+Shift+F7 Q高亮显C所有该文本Q按Esc高亮消失?span style="display: none"> 5H`rQKU </span> <br /> Ctrl+W 选中代码Q连l按会有其他效果<span style="display: none"> Ia87 </span> <br /> 选中文本Q按Alt+F3 Q逐个往下查扄同文本,q亮显C?span style="display: none"> ?Ge~7h- </span> <br /> Ctrl+Up/Down 光标跌{到第一行或最后一行下<span style="display: none"> m@eohmV> </span> <br /> Ctrl+B 快速打开光标处的cLҎ </p> <img src ="http://www.aygfsteel.com/EricGu/aggbug/262020.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/EricGu/" target="_blank">Eric Gu</a> 2009-03-26 09:35 <a href="http://www.aygfsteel.com/EricGu/archive/2009/03/26/262020.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IntelliJ IDEA使用技巧一览表http://www.aygfsteel.com/EricGu/archive/2009/03/26/262019.htmlEric GuEric GuThu, 26 Mar 2009 01:33:00 GMThttp://www.aygfsteel.com/EricGu/archive/2009/03/26/262019.htmlhttp://www.aygfsteel.com/EricGu/comments/262019.htmlhttp://www.aygfsteel.com/EricGu/archive/2009/03/26/262019.html#Feedback0http://www.aygfsteel.com/EricGu/comments/commentRss/262019.htmlhttp://www.aygfsteel.com/EricGu/services/trackbacks/262019.html在?/font>InelliJ IDEA的过E中Q通过查找资料以及一些自q摸烦Q发现这个众?/font>JavaE序员喜Ƣ的IDE里有许多值得一提的窍门,如果能熟l的它们应用于实际开发过E中Q相信它会大大节省你的开发时_而且随之而来的还会有那么一点点成就感:Q?/font>Try itQ?/font>
1、写代码时用Alt-InsertQ?/font>Code|Generate…Q可以创建类里面M字段?/font>getter?/font>setterҎ?/font>
2、右键点LҎ讎ͼ在文本的左边栏里Q激z速查菜单Q你可以快速设|?/font>enable/disable断点或者条件它的属性?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
3?/font>CodeCompletionQ代码完成)属性里的一个特D的变量是,Ȁz?/font>Ctrl-Alt-Space可以完成在或不在当前文g里的cd。如果类没有引入?/font>import标志会自动创建?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
4、?/font>Ctrl-Shift-V快捷键可以将最q用的剪脓板内定w择插入到文本。用时pȝ会弹Z个含有剪贴内容的对话框,从中你可以选择你要_脓的部分?/font>
5、利?/font>CodeCompletionQ代码完成)属性可以快速地在代码中完成各种不同地语句,Ҏ是先键入一个类名地前几个字母然后再?/font>Ctrl-Space完成全称。如果有多个选项Q它们会列在速查列表里?/font>
 '300')this.width='300';if(this.height>'200')this.height='200';" border=0>
6、用Ctrl-/?/font>Ctrl-Shift-/来注?/font>/反注释代码行与代码块?/font>
-/用单行注释标讎ͼ“//…”Q来注释/反注释当前行或者选择C码块。?/font>Ctrl-Shift-/则可以用块注释标讎ͼ“/ V;}HGn  
dy/?S GW  
/
”Q把所选块包围h。要反注释一个代码块在块中M一个地ҎCtrl-Shift-/卛_?/font>
7、按Alt-QQ?/font>View|Context InfoQ可以不需要移动代码就能查看当前方法地声明。连l按两次会显C当前所~辑的类名?/font>
8、?/font>Refactor|Copy Class…可以创徏一个所选择的类?#8220;副本”。这一点很有用Q比如,在你惌创徏一个大部分内容都和已存在类相同的类时?/font>
9、在~辑器里Ctrl-D可以复制选择的块或者没有所选块是的当前行?/font>
10?/font>Ctrl-WQ选择字)在编辑器里的功能是先选择脱字W处的单词,然后选择源代码的扩展区域。D例来_先选择一个方法名Q然后是调用q个Ҏ的表辑ּQ然后是整个语句Q然后包容块Q等{?/font>
11、如果你不想让指CZ件细节的“亮球”图标在编辑器上显C,通过?/font>Alt-Enterl合键打开所有事件列表然后用鼠标点击它就可以把这个事件文本附件的亮球|成非活动状态?/font>
q样以后׃会有指示Ҏ事g的亮球出CQ但是你仍然可以?/font>Alt-Enter快捷键用它?/font>
12、在使用CodeCompletionӞ可以用逗点Q?/font>.Q字W,逗号Q,Q分PQ)Q空格和其它字符输入弹出列表里的当前高亮部分。选择的名字会随着输入的字W自动输入到~辑器里?/font>
13、在M工具H口里?/font>Escape键都可以把焦点移到编辑器上?/font>
Shift-Escape不仅可以把焦点移到编辑器上而且q可以隐藏当前(或最后活动的Q工L口?/font>
F12键把焦点从编辑器Ud最q用的工具H口?/font>
14、在调试E序时查看Q何表辑ּ值的一个容易的Ҏ是在编辑器中选择文本Q可以按几次Ctrl-Wl合键更有效地执行这个操作)然后?/font>Alt-F8?/font>
15、要打开~辑器脱字符处用的cL者方?/font>Java文档的浏览器Q就?/font>Shift-F1Q右键菜单的External JavaDocQ?/font>
要用这个功能须要把加入览器的路径Q在“General”选项中设|(Options | IDE SettingsQ,另外q要把创建的Java文档加入到工E中Q?/font>File | Project PropertiesQ?/font>
16、用Ctrl-F12Q?/font>View | File Structure PopupQ键你可以在当前~辑的文件中快速导航?/font>
q时它会昄当前cȝ成员列表。选中一个要D的元素然后按Enter键或F4键。要L地定位到列表中的一个条目,只需键入它的名字卛_?/font>
17、在代码中把光标|于标记W或者它的检查点上再?/font>Alt-F7Q右键菜单中?/font>Find Usages…Q会很快地查扑ֈ在整个工E中使用地某一个类、方法或者变量的位置?/font>
18、按Ctrl-NQ?/font>Go to | Class…Q再键入cȝ名字可以快速地在编辑器里打开M一个类。从昄出来的下拉列表里选择cR?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
同样的方法你可以通过使用Ctrl-Shift-NQ?/font>Go to | File…Q打开工程中的?/font>Java文g?/font>
19、要D代码中一些地方用到的类、方法或者变量的声明Q把光标攑֜查看上再按Ctrl-B卛_。也可以通过?/font>Ctrl键的同时在查看点上单击鼠标键调{到声明处?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
20、把光标攑ֈ查看点上再按Ctrl-Alt-B可以DC个抽象方法的实现代码?/font>
21、要看一个所选择的类的承层ơ,?/font>Ctrl-HQ?/font>Browse Type HierarchyQ即可。也可以Ȁzȝ辑器中的l承关系视图查看当前~辑cȝl承关系?/font>
 '300')this.width='300';if(this.height>'200')this.height='200';" border=0>
22、?/font>Ctrl-Shift-F7Q?/font>Search | Highlight Usages in FileQ可以快速高亮显C当前文件中某一变量的用地斏V按Escape清除高亮昄?/font>
23、用Alt-F3Q?/font>Search | Incremental SearchQ在~辑器中实现快速查查找功能?/font>
?#8220;Search for:”提示工具里输入字W,使用头键朝前和朝后搜烦。按Escape退出?/font>
24、按Ctrl-Jl合键来执行一些你Ch?/font>Live Template~写。比如,?#8220;it”然后?/font>Ctrl-J看看有什么发生?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
25?/font>Introduce Variable整合帮助你简化代码中复杂的声明。D个例子,在下面的代码片断里,在代码中选择一个表辑ּQ?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
然后?/font>Ctrl-Alt-VQ?/font>Refactor | Introduce VariableQ就会出C面的l果Q?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
26?/font>Ctrl-Shift-J快捷键把两行合成一行ƈ把不必要的空格去掉以匚w你的代码格式?/font>
27?/font>Ctrl-Shift-BackspaceQ?/font>Go to | Last Edit LocationQ让你调转到代码中所做改变的最后一个地斏V?/font>
多按几次Ctrl-Shift-Backspace查看更深的修改历双Ӏ?/font>
28、用Tools | Reformat Code…Ҏ你的代码样式参考(查看Options | IDE Setting | Code StyleQ格式化代码?/font>
使用Tools | Optimize Imports…可以Ҏ讄Q查?/font>Options | IDE Setting | Code Style | ImportsQ自?#8220;优化”importsQ清除无用的imports{)?/font>
29、?/font>IDEA?/font>Live Templates | Live Templates让你在眨眼间创徏许多典型代码。比如,在一个方法里键入
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
再按Tab键看有什么事情发生了?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
?/font>Tab键在不同的模板域内移动。查?/font>Options | Live Templates获取更多的细节?/font>
30、要查看一个文件中修改的本地历ԌȀzd键菜单里?/font>Local VCS | Show History…。也怽可以D不同的文件版本,看看它们的不同之处再回滚C前的M一个版本吧?/font>
使用同样的右键菜单条目还可以看到一个目录里修改的历双Ӏ有了这个特性你׃会丢׃Q何代码了?/font>
31、如果要了解主菜单里每一个条目的用途,把鼠标指针移到菜单条目上再应用程序框架的底部的状态栏里就会显C它们的一些简短描qͼ也许会对你有帮助?/font>
32、要在编辑器里显C方法间的分隔线Q打开Options | IDE Settings | EditorQ选中“Show method separators”查盒Q?/font>checkboxQ?/font>
33?strong>?/strong>Alt-Up?/font>Alt-Down键可以在~辑器里不同的方法之间快速移动?/font>
34、用F2/Shift-F2键在高亮昄的语法错误间跌{?/font>
?/font>Ctrl-Alt-Down/Ctrl-Alt-Up快捷键则可以在编译器错误信息或者查找操作结果间跌{?/font>
35、通过?/font>Ctrl-OQ?/font>Code | Override Methods…Q可以很Ҏ地重载基本类地方法?/font>
要完成当前类implements的(或者抽象基本类的)接口的方法,׃?/font>Ctrl-IQ?/font>Code | Implement Methods…Q?/font>
36、如果光标置于一个方法调用的括号_?/font>Ctrl-P会显CZ个可用参数的列表?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
37、要快速查看编辑器脱字W处使用的类或方法的Java文档Q按Ctrl-QQ在弹出菜单?/font>Show Quick JavaDoc里)卛_?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
38、像Ctrl-QQ?/font>Show Quick JavaDoc昄z?/font>Java文档Q,Ctrl-PQ?/font>Show Parameter Info昄参数信息Q,Ctrl-BQ?/font>Go to Declaration跌{到声明)Q?/font>Shift-F1Q?/font>External JavaDoc外部Java文档Q以及其它一些快捷键不仅可以在编辑器里用,也可以应用在代码完成右键列表里?/font>
39?/font>Ctrl-EQ?/font>View | Recent FilesQ弹出最q访问的文g右键列表。选中文g?/font>Enter键打开?/font>
40、在IDEA中可以很Ҏ地对你的c,Ҏ以及变量q行重命名ƈ在所有用到它们的地方自动更正?/font>
试一下,把编辑器脱字W置于Q何一个变量名字上然后?/font>Shift-F6Q?/font>Refactor | Rename…Q。在对话框里键入要显C地新名字再?/font>Enter。你会浏览到使用q个变量地所有地方然后按“Do Refactor”按钮l束重命名操作?/font>
41、要在Q何视图(Project View工程视图Q?/font>Structure Viewl构视图或者其它视图)里快?/font>
选择当前~辑地部分(c,文gQ方法或者字D)Q按Alt-F1Q?/font>View | Select in…Q?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
42、在“new”字符后实例化一个已知类型对象时也许你会用到SmartType代码完成q个Ҏ。比如,键入
 '300')this.width='300';if(this.height>'200')this.height='200';" border=0>
再按Ctrl-Shift-SpaceQ?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
43、通过使用SmartType代码完成Q在IDEA中创建接口的整个匿名implementation也是非常Ҏ的,比如Q对于一?/font>listenerQ监听器Q,可以键入
  Component component;
  component.addMouseListener(
    new w w <caret is here> 
  );
然后再按Ctrl-Shift-Space看看有什么发生了?/font>
44、在你需要设|一个已知类型的表达式的值时?/font>SmartType代码完成也很有帮助。比如,键入
String s = (<caret is here> 
再按Ctrl-Shift-Space看看会有什么出现?/font>
45、在所有视N都提供了速查功能Q在树里只需键入字符可以快速定位到一个条目?/font>
46、当你想用代码片断捕捉异常时Q在~辑器里选中q个片断Q按Ctrl-Alt-TQ?/font>Code | Surround with…Q然后选择try/catch。它会自动生代码片断中抛出的所有异常的捕捉块。在Options | File Templates | Code tab中你q可以自己定制生捕捉块的模ѝ?/font>
用列表中的其它项可以包围别的一些结构?/font>
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
47、在使用代码完成Ӟ?/font>Tab键可以输入弹出列表里的高亮显C部分?/font>
不像?/font>Enter键接受输入,q个选中的名字会覆盖掉脱字符双名字的其它部分。这一点在用一个方法或者变量名替换另一个时特别有用?/font>
48、在声明一个变量时代码完成Ҏ会l你昄一个徏议名。比如,开始键?/font>“private FileOutputStream”然后?/font>Ctrl-Space
'300')this.width='300';if(this.height>'200')this.height='200';" border=0>
?/font>Options | IDE Setting | Code Style中还可以为本地变量,参数Q实例及静态字D定制名字?br />


Eric Gu 2009-03-26 09:33 发表评论
]]>
վ֩ģ壺 ͳ| | ΢| | | | | | üɽ| Т| ˮ| ϰˮ| ɽ| ʡ| ɽ| | ʯ| | | | ϰ| | | ƾ| | | Զ| | ʦ| | ˴| | Ȫ| | ɽ| ػ| | | | | ֦|