2015年9月29日星期二

Joda-time介绍

http://www.ibm.com/developerworks/cn/java/j-jodatime.html
http://blog.csdn.net/zeus_9i/article/details/32318771?utm_source=tuicool

lombok介绍

参考:
http://www.blogjava.net/fancydeepin/archive/2012/07/12/lombok.html
http://jnb.ociweb.com/jnb/jnbJan2010.html

lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码。
前置条件:

  • 安装lombok至eclipse
  • 引入lombok
lombok 注解:
    lombok 提供的注解不多,可以参考官方视频的讲解和官方文档。
    Lombok 注解在线帮助文档:http://projectlombok.org/features/index.    下面介绍几个我常用的 lombok 注解:
        
@Data   :注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
        
@Setter:注解在属性上;为属性提供 setting 方法
        
@Getter:注解在属性上;为属性提供 getting 方法
        
@Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
        
@NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
        
@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
        @NonNull: 注解在属性上,会对setter和构造方法进行NPE判断
        @ToString:注解在类上
        @EqualsAndHashCode
  
@Log4j
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true, exclude = "id")
@EqualsAndHashCode(exclude = { "id" })
public class Person {

    @NonNull
    private String id;
    private String name;
    private String identity;
}

@Cleanup

The @Cleanup annotation can be used to ensure that allocated resources are released. When a local variable is annotated with @Cleanup, any subsequent code is wrapped in a try/finally block that guarantees that the cleanup method is called at the end of the current scope. By default @Cleanup assumes that the cleanup method is named "close", as with input and output streams. However, a different method name can be provided to the annotation's value parameter. Only cleanup methods which take no parameters are able to be used with this annotation.
  
Lombok annotated code:
public void testCleanUp() {
    try {
        @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write(new byte[] {'Y','e','s'});
        System.out.println(baos.toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Equivalent Java source code:
public void testCleanUp() {
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            baos.write(new byte[]{'Y', 'e', 's'});
            System.out.println(baos.toString());
        } finally {
            baos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Synchronized

Using the synchronized keyword on a method can result in unfortunate effects, as any developer who has worked on multi-threaded software can attest. The synchronized keyword will lock on the current object (this) in the case of an instance method or on the class object for a static method. This means that there is the potential for code outside of the control of the developer to lock on the same object, resulting in a deadlock. It is generally advisable to instead lock explicitly on a separate object that is dedicated solely to that purpose and not exposed in such a way as to allow unsolicited locking. Project Lombok provides the @Synchronized annotation for that very purpose.
Annotating an instance method with @Synchronized will prompt Lombok to generate a private locking field named $lock on which the method will lock prior to executing. Similarly, annotating a static method in the same way will generate a private static object named $LOCK for the static method to use in an identical fashion. A different locking object can be specified by providing a field name to the annotation's value parameter. When a field name is provided, the developer must define the property as Lombok will not generate it.
Lombok annotated code:
private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");

@Synchronized
public String synchronizedFormat(Date date) {
    return format.format(date);
}
Equivalent Java source code:
private final java.lang.Object $lock = new java.lang.Object[0];
private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");

public String synchronizedFormat(Date date) {
    synchronized ($lock) {
        return format.format(date);
    }
}

@SneakyThrows

@SneakyThrows is probably the Project Lombok annotation with the most detractors, since it is a direct assault on checked exceptions. There is a lot of disagreement with regards to the use of checked exceptions, with a large number of developers holding that they are a failed experiment. These developers will love @SneakyThrows. Those developers on the other side of the checked/unchecked exception fence will most likely view this as hiding potential problems.
Throwing IllegalAccessException would normally generate an "Unhandled exception" error if IllegalAccessException, or some parent class, is not listed in a throws clause:
When annotated with @SneakyThrows, the error goes away.
Screenshot of a method annotated with @SneakyThrows and generating no error in Eclipse.
By default, @SneakyThrows will allow any checked exception to be thrown without declaring in the throws clause. This can be limited to a particular set of exceptions by providing an array of throwable classes ( Class<? extends Throwable>) to the value parameter of the annotation.
Lombok annotated code:
@SneakyThrows
public void testSneakyThrows() {
    throw new IllegalAccessException();
}
Equivalent Java source code:
public void testSneakyThrows() {
    try {
        throw new IllegalAccessException();
    } catch (java.lang.Throwable $ex) {
        throw lombok.Lombok.sneakyThrow($ex);
    }
}
A look at the above code and the signature of Lombok.sneakyThrow(Throwable) would lead most to believe that the exception is being wrapped in aRuntimeException and re-thrown, however this is not the case. The sneakyThrow method will never return normally and will instead throw the provided throwable completely unaltered.

常用Java库

  • 参考:http://www.oschina.net/translate/better-java?from=20150927
  • https://github.com/akullpp/awesome-java
    •   jUnit 4
    •   jMock
    •   AssertJ
    •   Apache Commons
    •   Guava
    •   Gson
    •   Java Tuples
    •   Joda-Time
    •   Lombok
    •   Play framework
    •   SLF4J
    •   jOOQ
    •  Missing Features
    •   Testing

Apache Commons
Apache Commons 项目有一堆实用的库。Apache Commons Pool可以便于实现各种池!
Commons Codec 有许多针对 Base64 和 16 进制字符串的编码/解码方法。你就不要再浪费时间再去重新编写他们了。
Commons Lang 是针对 String 的创建和操作,字符集以及一堆实用工具方法的库。
Commons IO 拥有你可以想象得到的所有文件相关的方法。它有 FileUtils.copyDirectoryFileUtils.writeStringToFileIOUtils.readLines 以及更多的东西。

Guava

Guava 是 Google 的优秀的补充Java所缺的库。几乎很难提交我所喜欢的有关于这个库的所每个功能,但我会试试。
Cache 是获取一个内存缓存的简单方法,可以被用来缓存网络访问,磁盘访问,记忆函数或者任何实在的数据。只要实现一个 CacheBuilder 就能告诉 Guava 如何去构建你的缓存,一切尽在你的掌握之中 !
Immutable 集合。有一堆这样东西 : ImmutableMap,ImmutableList, 或者如果那是你的风格的话,就还有 ImmutableSortedMultiSet .
我也喜欢用 Guava 的方式编写不可变的集合:
?
1
2
3
4
5
// Instead of
final Map<String, Widget> map = new HashMap<String, Widget>();
// You can use
final Map<String, Widget> map = Maps.newHashMap();
还有针对 ListsMapsSets 以及更多集合的静态类。 他们更清晰和可读。
如果你还在 Java 6 或者 7 的坑里面, 你可以使用 Collections2 类, 它拥有像 filter 和 transform 这样的方法. 能让你在没有 Java 8 对流的支持下写出流畅的代码。
Guava 也有一些简单的东西, 比如 Joiner 能用分隔符将字符串连接起来,以及一个通过忽略它们来 处理中断的类.

Gson

Google的Gson 库是一个简单快速的JSON转换库。像下面这样运作:
?
1
2
3
final Gson gson = new Gson();
final String json = gson.toJson(fooWidget);
final FooWidget newFooWidget = gson.fromJson(json, FooWidget.class);
相当简单且令人愉悦。Gson用户手册 有许多的示例。

Java Tuples

Java经常令我头疼的一点就是他的标准库里面并没有内置元组。幸运的是, Java tuples 项目解决了这个问题。
它易于使用而且表现很棒:
?
1
2
3
Pair<String, Integer> func(String input) {
    // something...
    return Pair.with(stringResult, intResult);}

Joda-Time

Joda-Time 是我所使用过的最棒的时间库. 简答,直接,易于测试. 夫复何求?
所以你只要在如果没有使用Java8时使用这个库,因为Java8有了新的 日期时间 库。

Lombok

Lombok 是一个有趣的库。它能通过注解让你减少 Java 所严重遭受的样板式代码。
想要为你的类变量加入设置器和获取器? 简单:
?
1
2
public class Foo {
    @Getter @Setter private int var;}
现在你可以这样做:
?
1
final Foo foo = new Foo();foo.setVar(5);
还有 更多的东西。我还没有将 Lombok 用于生产环境,但我迫不及待的想要这么做了。

Play framework

好的选择 Jersey 或者 Spark
在Java中实现 RESTful web 服务又两个主要的阵营 : JAX-RS 和其余一切。
JAX-RS 是传统的方式。你可以使用诸如Jersey之类的东西来将注解结合接口和实现来组织 web 服务。这里有意思的是你可以简单的从接口类创建出客户端。
Play framework 是 JVM 的 web服务的一个异类:你会有一个路由文件,然后你要编写在这些路由中被引用的类。它实际上是一个完整的 MVC 框架, 但是你可以简单地只把他用于 REST web 服务。
它在 Java 和 Scala 上都能用。它稍有偏向 Scala 优先,不过在Java中也还好.
如果你用过Python中向Flash这样的微型框架, 你就能熟悉 Spark。它在 Java 8 上能运行得很好。

SLF4J

有许多Java日志的解决方案。我喜欢的就是 SLF4J 因为它的极度的可插入性,并且可以同时结合来自不同日志框架的日志. 有没有过一个使用了 java.util.logging, JCL, 以及 log4j 的古怪项目? SLF4J 为你而生。
两页篇幅的操作手册 就是你入门所需要的。

jOOQ

我不想换重量级的 ORM 框架,因为我喜欢 SQL。因此我写了许多 JDBC 模板, 而这样就有点难以维护。 jOOQ 是一个更好的解决方案。
他能让你用 Java 以一种更加类型安全的方式编写SQL:
?
1
2
3
4
5
6
7
8
9
// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result = 
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
    .from(BOOK)
    .join(AUTHOR)
    .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
    .where(BOOK.PUBLISHED_IN.equal(1948))
    .fetch();
使用这个和 DAO 模式, 你可以使得访问数据库变得轻而易举。

测试

测试对于你的软件至关重要。这些包能使得测试更简单。

jUnit 4

jUnit 不需要介绍了。它是Java中单元测试的标准工具.
而你可能不会发挥 jUnit 的全部潜能。jUnit 支持 参数化测试,,让你不用编写过多样板代码的 规则,随机测试特定代码的 理论, 以及 假设

jMock

如果依赖注入那块你弄好了的话,这时候它就能发挥点作用了 : 模拟那些有副作用的代码 (比如同一个REST服务器进行交互) 并且仍然可以对调用它的代码进行断言。
jMock 是标准的Java模拟工具。它看起来像这样:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class FooWidgetTest {
    private Mockery context = new Mockery();
    @Test
    public void basicTest() {
        final FooWidgetDependency dep = context.mock(FooWidgetDependency.class);
        context.checking(new Expectations() {{
            oneOf(dep).call(with(any(String.class)));
            atLeast(0).of(dep).optionalCall();
        }});
        final FooWidget foo = new FooWidget(dep);
        Assert.assertTrue(foo.doThing());
        context.assertIsSatisfied();
    }}
这里通过 jMock 设置了一个 FooWidgetDependency,然后加入了一个预期( expectation)。我们预期 dep 的 call 方法会使用某个字符串被调用一次并且 dep 的 optionalCall 方法会被调用0到多次。
如果你要一次又一次设置相同的依赖,你可能应该将那些放到一个 测试夹具(est fixture)中,并将 assertIsSatisfied 放到一个 @After 夹具中。

AssertJ

你曾经用 jUnit 这样做过吗?
?
1
2
3
4
5
final List<String> result = some.testMethod();
assertEquals(4, result.size());
assertTrue(result.contains("some result"));
assertTrue(result.contains("some other result"));
assertFalse(result.contains("shouldn't be here"));
这都是烦人的样板代码。 AssertJ 会把这些都干掉。你可以将同样的代码转换成这样:
?
1
2
3
assertThat(some.testMethod()).hasSize(4)
                             .contains("some result""some other result")
                             .doesNotContain("shouldn't be here");
这样流畅的接口让你的测试更加可读. 夫复何求?