Tag Archives: java

有关Java泛型的类型擦除(type erasing)

自从Java 5引入泛型之后,Java与C++对于泛型不同的实现的优劣便一直是饭后的谈资。在我之前的很多training中,当讲到Java泛型时总是会和C++的实现比较,一般得出的结论是 Java使用类型擦除(type erasing),泛型信息只在编译时供javac作类型检查用,在编译后便被javac擦除,因此无法被反射 C++使用代码模板实现泛型,即在预处理时会生成类似「list_int」,「list_char」等的泛型类,虽然解决Java的运行时伪泛型的问题,但是会导致编译后的代码呈线性增长 于是在一般情况下,Java的类型擦除实现较优 这三条已经比绝大多数的Java培训讲师讲得深刻了。但是如果下面有人问「在什么情况下C++的实现方式较优」时,除了无法被反射,我很难现抓一个有说服力的例子。今天,Spring的RestTemplate终于给了我这个例子 我遇到的问题如下(阅读需要有一些Spring MVC、REST基础) 有一个返回类型为List的MVC方法: @RequestMapping(value = "…", method = RequestMethod.GET) @ResponseBody public List<DomainClass> doSomethingREST() {     List<DomainClass> domainObjs = … ;     return domainObjs; } @RequestMapping(value = “…”, method = RequestMethod.GET) @ResponseBody public List<DomainClass> doSomethingREST() { List<DomainClass> domainObjs = … ; return domainObjs; } 在运行时,Spring MVC会将List转换成JSON字符串并返回至客户端。但是如果我在另一个service中使用RestTemplate直接调用该REST接口,问题便来了: List<DomainClass> read more »

使用Spring LDAP ODM操作LDAP

Spring Source真的是个很神奇的开源社区,从《J2EE without EJB》开始为大家所知晓,到把IoC、AOP大范围地带到大家的开发模型中,再到和Hibernate、Struts组成每个Java函授学校必教的“SSH”组合,从此绿遍大江南北…… 在国内,大马路上随便抓一个Java程序员,10个里有9个半知道Spring;有9个知道怎么把SSH“组装”到一起(是的,“组装”,和流水线上的蓝领熟练工没有本质区别);有9个半知道IoC、AOP;有2个知道IoC和AOP的本质;有3个知道Spring其实分为core、context、orm、tx等不同子框架;有1个知道Spring 3之后可以用annotation取代之前版本大部分的xml配置;有2个知道Spring mvc和security;有半个知道其实Spring的子框架远不止这些……这就是我们当前Java码农们的实际情况。而造成这一局面的,我谓之三害——高校计算机系功利的培养模式、以北大青鸟为首的各种速成班的祸害和程序员们自己懒惰、人云亦云、拒绝思考的慢性自杀 牢骚发完,本文将通过介绍Spring的两个子框架:Spring LDAP和Spring LDAP ODM,来实现对LDAP的操作 项目主页:http://www.springsource.org/ldap,该框架通过提供和ORM中相似的机制对LDAP相关操作进行封装,主要包括: 类比SessionFactory的LdapContextSource 类比HibernateTemplate等的LdapTemplate 伪事务支持,能否与tx框架的TransactionManager混用未知 类比JPA的使用@Entry、@Attribute、@Id标注的ODM——Object Directory Mapping 本文(原先)目标:使用ODM将User类与LDAP中的实体进行映射,LDAP中的实体的objectClass包括inetOrgPerson,organizationalPerson,person,shadowAccount和top 相关配置文件、代码在http://static.springsource.org/spring-ldap/docs/1.3.x/reference/html/上已经很详细了,这里只是做一点旁注,全部来自于这几天和Spring LDAP的斗智斗勇 对于shadowAccount的shadowLastChange域,值是一个整形,至于具体含义网上没有找到解释,试了几次之后发现是从1970-1-1 00:00:00至今的天数,如果model里定义的是Date类型的话,需要自行实现org.springframework.ldap.odm.typeconversion.impl.Converter接口进行转换 对于@Entry标记,其中的objectClasses定义必须与objectClass完全一致。在新建和查询object时,ODM会根据此标记进行匹配,无需再指定objectClass 每个entry必须指定@Id字段,类型为javax.naming.Name,其实就是DN。但是若在LdapContextSource中指定了base,则DN将会按照base截取相对路径。比如,DN为cn=user,ou=users,dc=jayxu,dc=com,base为dc=jayxu,dc=com,则取出的user对象DN为cn=user,ou=users 如果使用Spring MVC对LDAP对象进行JSON序列化,必须注意javax.naming.Name中的某些字段无法被序列化,所以在转换成JSON之前需要将DN置null。一种方法是使用@JsonIgnoreProperties标记model类,比如:@JsonIgnoreProperties(“dn”) 对于不需要与LDAP进行映射的字段使用@Transient进行标记 考虑使用org.springframework.ldap.pool.factory.PoolingContextSource引入连接池 如果事务中需要与JDBC进行互操作,需要使用org.springframework.ldap.transaction.compensating.manager.ContextSourceAndDataSourceTransactionManager作为tx manager

祝贺:发布《Java虚拟机规范 (Java SE 7 中文版)》

原文转自:http://icyfenix.iteye.com/blog/1256329 《Java虚拟机规范 (Java SE 7 中文版)》是一份根据《Java Virtual Machine Specification (Java SE 7)》翻译的、非官方的、以Open Document形式发布的文档。 本译文由ItEye社区三位水友IcyFenix、wupuyuan、langyu合作完成,我们的翻译工作完全基于技术研究目的,任何人也都可以在以技术研究为目的前提下任意阅读、传播、使用这份文档。但没有得到原文作者和译者授权,不得用于商业出版。 ◎ 全文PDF下载地址:Download (@iteye.com) ◎ 如果没有ItEye账号的朋友,可在此下载:Download (@icyfenix.com) ◎ 译文勘误、更新地址:http://www.icyfenix.com/jvms_javase7_cn 翻译一本书,远远比读完一本书来的辛苦。不过回头看来,那些辛苦比起翻译过程中对自己的提升和认识到的朋友,收获是远远大于付出。如果这本书能再为其他人带来一点方便和用处,那我们就更加欣慰了。如果本书真的对您有用,希望您能: ◎ 向我们反馈本书中翻译的问题,以便我们能持续改进译文的质量。 ◎ 向朋友传播本书(如帮我转发一下此微博),以便我们的工作能发挥更大的价值。 译者序 从1999年4月出版的《Java虚拟机规范(第二版)》至今,已经超过12年,虽然此规范在JDK 5发布的时候作了较大的更新,但却始终没有发布完整的规范。在今年6月28日,最新的《Java虚拟机规范(Java SE 7版)》终于完成并在7月份正式发布。对于想了解Java虚拟机的程序员来说,《Java虚拟机规范》是必须阅读的,对于想深入了解Java语言细节的程序员,阅读《Java虚拟机规范》也有极大好处,但是《Java虚拟机规范》、《Java语言规范》发布十余年,一直没有中文译本,这让中国不少对Java虚拟机感兴趣,但英语能力较弱的程序员都被拒之门外。 在2011年初,《Java虚拟机规范(Java SE 7版)》还是草稿状态时,我就开始关注这本书,并陆续对其中第1、2、6、7章进行了翻译,到2011年9月时完成了200余页的译稿。这时候又在国内著名Java社区ItEye中结识了另外两名译者吴璞渊和冶秀刚,我们在随后的两个多月的时间里共同完成了其余章节的翻译和校对。 《Java虚拟机规范》并非某一款虚拟机实现的说明书,它是一份保证各个公司的Java虚拟机实现具备统一外部接口的契约文档,书中的概念和细节描述曾经与Sun的早期虚拟机的实现高度吻合,但是随着技术的发展,高性能虚拟机真正的细节实现方式已经渐渐与虚拟机规范所描述的内容产生了越来越大的差距。原作者也在书中不同地方反复强调过:虚拟机规范中所提及的“Java虚拟机”皆为虚拟机的概念模型而非具体实现。实现只要保证与概念模型最终等效即可,而具体实现的方式无需受概念模型束缚。因此通过虚拟机规范去分析程序的执行语义问题(虚拟机会做什么)时,但分析程序的执行行为问题(虚拟机是怎样做的、性能如何)则意义不大,如需对具体虚拟机实现进行调优、性能分析等,我推荐在本书基础上继续阅读《Java Performance》和《Oracle JRockit The Definitive Guide》等书。 在翻译过程中,我们尽最大努力保证作品的准确性和可读性,力求在保证语义准确的前提下,尽可能使用通俗易懂的方式向给各位读者介绍Java虚拟机的约束与运作原理。为此目标,我们在专有技术名词、偏僻词中用括号保留了原文、专门在多处读者理解起来可能有困难的地方,添加了“译者注”加以解释。 囿于我们的水平和写作时间,书中难免存在不妥之处,大家如有任何意见或建议都欢迎通过以下邮件地址与我联系:[email protected]。本书的勘误与最新版本可以在以下网址中获取:http://www.icyfenix.com/jvms_javase7_cn/ 最后,请允许我再介绍一下本书三位译者的技术背景与分工: 周志明(www.icyfenix.com & weibo.com/icyfenix):远光软件平台开发部部门经理,平台架构师,不愿意脱离编码的一线码农。著有《深入理解Java虚拟机:JVM高级特性与最佳实践》。关注各种Java应用,略懂OSGi、Java虚拟机和工作流。在本书翻译工作中负责全文统稿;前言和第1、2、6、7章的翻译;第3、4、5章的校审工作。 吴璞渊(wupuyuan.iteye.com):就职于西门子,偏向程序和工作流设计,喜好Java各种新技术并倒腾。在本书翻译工作中负责第3章以及第4章的1至7节。。 冶秀刚(langyu.iteye.com):思科平台工程师,从事分布式系统的研究与开发,爱好Java平台技术且正在努力成长中。在本书翻译工作中负责第5章及第4章的9至11节。

X and XX Usgaes for Java

-X -Xmixed mixed mode execution (default) -Xint interpreted mode execution only -Xbootclasspath:<directories and zip/jar files separated by ;> set search path for bootstrap classes and resources -Xbootclasspath/a:<directories and zip/jar files separated by ;> append to end of bootstrap class path -Xbootclasspath/p:<directories and zip/jar files separated by ;> prepend in front of bootstrap class path -Xnoclassgc read more »

Differences Among Greedy, Reluctant, and Possessive Quantifiers (for RexExp in Java)

There are subtle differences among greedy, reluctant, and possessive quantifiers. Greedy quantifiers are considered “greedy” because they force the matcher to read in, or eat, the entire input string prior to attempting the first match. If the first match attempt (the entire input string) fails, the matcher backs off the input string by one character read more »

关于『C++11 中值得关注的几大变化(详解)』

博客更新得越来越不频繁,一方面是忙+懒,另一方面围脖带来的写作习惯的变化,越来越多的想法使用140字以内的只字片语发布在围脖上。而WP上还 没有像twitter tools一样的围脖反向更新工具,所有的围脖相关工具不是登录绑定就是发博同步至围脖。可见国内互联网产品业余开发人员的同质与乏善可陈,难道要我自己 用PHP去写一个? 最近发现在team里的一些讨论邮件还是有点意思的,我发表了一些观点,也进行了一些讨论。这些邮件算是一个观点展示、碰撞的积累。今天开始转贴一些,当然前提是非IBM confidential的。以下是第一篇   C++11 中值得关注的几大变化(详解) 原文出自酷壳   Me:Like Java & C#, C++ started to introduce many language sugars into the new version 11 (to make the language up-to-date), esp. for Lambda grammar, which is deferred to Java 8. Another highlight is the standard thread lib, wonder if it supports multi-core architecture read more »

Don’t Use Java 7, For Anything [zz]

From here. Shit happens, Oracle wanna risk the fame of Java?!   Java 7 GA was released today, but as noted by Uwe Schindler, there are some very frightening bugs in HotSpot Loop optimizations that are enabled by default. In the best case scenario, these bugs cause the JVM to crash. In the worst case read more »

有关Character.isLetter()和Character.isLetterOrDigit()

在项目中有时候可能需要判断输入的是否全是英文或数字,如果你不善于使用正则,JDK中提供了Character类对字符进行操作,其中的 isLetter和isLetterOrDigit方法貌似可以做到这一点。但是如果你试下下面的代码,你会失望的: System.out.println(Character.isLetter(’中’)); System.out.println(Character.isLetter(‘中’)); 很不幸地,Java天生提供了对unicode的支持,因此在她眼里中文也是“letter”,所以上面打印出的是true……。替代方案是,使用Apache Commons子项目中的lang库,CharUtils的isAsciiAlpha和isAsciiAlphanumberic可以帮助你只对英文字母进行判断 多说一句,commons项目是个大宝库,其中提供了大量对JDK的增强API,lang库就是对java.lang的增强,比如使用反射生成toString的ToStringBuilder,使用反射生成hashCode的HashCodeBuilder,使用反射生成equals的EqualsBuilder等等,大家可以慢慢自己发掘~

如何在Hibernate中让SQLServer使用nvarchar代替varchar

有关SQLServer中varchar和nvarchar的区别可以直接去google。一般在中文系统中应该使用nvarchar作为字符串的对应类型,但是Hibernate中的默认实现SQLServerDialect使用了varchar。以下方法可以简单地转为使用nvarchar: 自己写一个dialect,继承SQLServerDialect,在构造器中将原先varchar类型的注册声明覆盖: registerColumnType(Types.VARCHAR, "nvarchar($l)"); registerColumnType(Types.VARCHAR, “nvarchar($l)”); 千万注意,“$”后面的是字段长度的占位符,是“l(ength)”,而不是数字“1”(因为看hibernate的doc时没分清“l”和“1”,浪费了我一上午去找原因) 然后在hibernate的配置文件中将hibernate.dialect的值设为你的dialect实现类就OK了

误区!double类型做加减法不会有误差?

如果你跟我一样以为Java的double类型只有在作乘除法时才会出现误差,那试一下在Java里执行一下下面的代码: public static void  main(String[] args) {     System.out.println(44.42 + 710.79 + 44.42 +  88.85); } public static void main(String[] args) { System.out.println(44.42 + 710.79 + 44.42 + 88.85); } 执行前先猜一下结果,是会输出888.48么?还是……? 建议:对于和钱有关的计算,不论加减乘除,统一使用 BigDecimal! 然而不多久之后同事告诉我另一个BigDecimal的问题,试一下下面的代码: System.out.println(new BigDecimal(0.99).setScale(2, RoundingMode.DOWN).toString()); System.out.println(new BigDecimal(0.99).setScale(2, RoundingMode.DOWN).toString()); 结果是令人发指的0.98! 看了一下 BigDecimal(double)的源码,其中使用位操作分别提取了0.99浮点值的整数部分和纯小数部分,或者说是2的正数次幂和负数次幂部分。而这样提取出来的值纯小数部分本身就是近似的,与直接使用double类型没有本质区别,这是浮点表示法决定的,再经过2位截取后就产生了误差 而当使用BigDecimal(String)的构造器时得到的是精确值,因为该构造器将数字使用科学计数法表示,即 0.99表示为99*10^-2,这样做运算时先对齐至相同的整数位再进行计算 因此,对上面的补充是:如果要获取最精确的结果,请使用BD+字符串类型的构造器

无觅相关文章插件,快速提升流量