解惑

解己之惑,解人之惑

分类:Java (第4页共20页)

Java技术

一个通用的面向对象的查询接口

现在做持久化基本上都会用到ORM,现在最通用的解决方案当然就是Hibernate以及由之引申出来的EJB3的持久化方案,我们在做DAO层的时候经常是直接写HQL,并不是说它不好,而是不够通用。例如本来有个功能是查询某种类型的User,但是需要额外的过滤和排序,那么就需要拼HQL的,不太好维护,所以有一个面向对象的查询接口还是比较好。
下面就是这个雏形,是我现在的项目中用到的,抛砖引玉吧。
下面是全部的类和主要的方法,其他的方法都忽略了,可以到Google Code下载全部的源代码。
阅读全文

继承中的Serializable问题

为了实现深度克隆,一个最简单的办法就是让需要克隆的类全部实现Serializable,然后:
            ByteArrayOutputStream byteArrOs = new ByteArrayOutputStream();
            ObjectOutputStream objOs = new ObjectOutputStream(byteArrOs);
            objOs.writeObject(this);

            ByteArrayInputStream byteArrIs = new ByteArrayInputStream(byteArrOs.toByteArray());
            ObjectInputStream objIs = new ObjectInputStream(byteArrIs);
            Object deepCopy = objIs.readObject();
在实现的时候遇到一个问题,就是我的this的类的父类忘记增加implements Serializable,导致克隆出来的对象丢失了父类中的信息,解决方法当然也很简单了,在父类加上implements Serializable就行了。
所以用这个方式的时候一定要小心,就是你需要深度克隆的对象相关的所有对象都要implements Serializable,否则那部分不会被克隆,而且没有任何异常。那些类的子类也需要加上。

搭建自己的云:Hadoop

呵呵,原来自己也可以搭云玩了,而且是Java的云,这是apache下的开源项目,是根据google发布的一些论文构建的,虽然根据这位老兄的实验,在集群环境下的性能并不是特别理想,但是还是值得一试的,毕竟代表了最先进的IT技术之一嘛。最后提一下这个Hadoop中文研究院,有兴趣不想看因为的可以看看这个网站。

还有没有漏洞的算法吗?

刚刚在infoq上看到的新闻:Quicksort算法标准实现中发现严重安全漏洞,这个年头还有安全的代码吗?还有没有漏洞的算法吗?

Web Service的方法有很多限制

这个是这段时间发现的,Web Service的方法限制很多,简单的列举下这段时间遇到的:

  • 输入和输出参数不能用Collection等接口,如果用List最好直接用ArrayList,而且ArrayList也不能作为输入参数,只能作为返回值类型
  • 输入参数不能用Class类型
  • ArrayList和Class都可以wrapper以后用,也就是输入参数里面的类型里面包含ArrayList或Class是没有问题的

最后发点感慨,JAXB的默认实现要求比较多,可能是因为JDK的很多类那个时候是没有考虑到这些。

性能测试

上周基于JUnit写了个简单的性能测试框架,其实就是用了下Annotation,发现还是很好用的。

/**
 * Performance test annotation.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PerformanceTest
{
    public String name() default "";
    public int times();
    public boolean stopOnError() default false;
}

阅读全文

查看Class文件的版本

呵呵,同事的类编译出来以后在Tomcat里面运行一直报错,说类版本不对,他已经把JDK1.6卸载了,上网查了下,一个简单的类就可以读出class文件的版本:

import java.io.*;

public class ClassVersionChecker {
    public static void main(String[] args) throws IOException {
        for (int i = 0; i < args.length; i++)
            checkClassVersion(args[i]);
    }

    private static void checkClassVersion(String filename)
        throws IOException
    {
        DataInputStream in = new DataInputStream
         (new FileInputStream(filename));

        int magic = in.readInt();
        if(magic != 0xcafebabe) {
          System.out.println(filename + " is not a valid class!");;
        }
        int minor = in.readUnsignedShort();
        int major = in.readUnsignedShort();
        System.out.println(filename + ": " + major + " . " + minor);
        in.close();
    }
}

major  minor Java platform version
45       3           1.0
45       3           1.1
46       0           1.2
47       0           1.3
48       0           1.4
49       0           1.5
50       0           1.6

原文在这里

Abstract Class和Interface

呵呵,这个问题可能大部分人从来不会想到,这里要说的不是谁好谁坏,也不是设计,而是性能问题。

今天一个同事问我,听说Interface有性能问题,比Abstract Class慢很多,知道怎么回事吗?我以前从来没有听说过,后来google了下,还真的发现有人讨论这个:Interface VS Abstract class

结论是Interface比Abstract Class慢很多,原因是调用Interface方法的指令是invokeinterface,而调用Abstract Class的方法指令是invokevirtual,而在调用invokeinterface时的真正的参数多一个参数指定参数数量,呵呵,这个小小的区别导致两个指令可能有10倍以上的差别。至于详细的区别,大家也可以看这个帖子。另外这个文章说的更加全面,比较了四个invokeXxx指令的性能以及字节码,结论是:静态方法调用最快,而通过接口调用方法最慢(比invokevirtual慢了3-4倍),调用private的方法比调用一般的方法稍快。

用TeamCity构建Continuous Integration

TeamCity是JetBrains公司(也就是出品Intellij的公司)出品的,可以免费使用,支持所有常见的VCS系统(cvs, SVN, perforce, cleancase, ssf等),也支持所有常见的build系统(ant, maven以及.net下的那些),由于有其它的项目组在用,今天我们也用了下,发现还是很简单的。

下载最新的4.0版本,大概218M,安装完成后可以直接启动Server,其实就是Tomcat6的应用,打开浏览器,第一次使用的时候会创建Admin账号,创建完后就可以创建工程,创建build config,配置VCS和Builder以及Trigger,选择需要使用的Agent或者安装一个新的Agent。今天主要是配置Perforce的VCS出了点问题,开始选择的是client模式,但是应该选择client mapping模式并配置好映射路径(文档中有例子)。

刚开始确实有点摸不着头绪,但是配置成功后发现还是很简单的,比较直观。

JUnit4和Ant的恩怨

今天继续写build脚本,加JUnit的target,但是我开始用的是Ant1.6.2,但是JUnit用的是4.1,发现编译正常,但是运行的时候出错,报的错是ClassNotFoundException,google了下,发现很多人有类似的问题,但是没有多少好的答案,最后在同事的一起努力下搞定,有两种情况:

  • 使用Ant1.6.2或者1.6.5的情况下,修改Test类,增加下面的方法:

public static junit.framework.Test suite() {
                return new JUnit4TestAdapter(TestXxxx.class);
}

还有就是注意ClassPath的定义:

    <path id="classpath">
        <fileset dir="${basedir}">
             <include name="lib/**/*.jar"/>
        </fileset>
        <fileset dir="${web.dir}">
              <include name="WEB-INF/lib/**/*.jar"/>
        </fileset>
  <pathelement path="${class.dir}"/>
    </path>

开始的时候,那个pathelement部分也是和其他的一样使用的fileset,不知道为什么必须使用pathelement才好使。

  • 使用Ant1.7.0的情况下,就不需要修改Test用那个什么JUnit4TestAdapter了。注意,好像Ant1.7.1有问题,可能是我的那个classpath搞的,没有仔细试过,报的错误是Can not open zip file,没有具体指出是那个zip文件找不到,根据google的一些结果建议回滚到Ant1.7.0。
更早的文章 更新的文章

© 2024 解惑

本主题由Anders Noren提供向上 ↑