http://www.ibm.com/developerworks/cn/java/j-jodatime.html
http://blog.csdn.net/zeus_9i/article/details/32318771?utm_source=tuicool
2015年9月29日星期二
lombok介绍
参考:
http://www.blogjava.net/fancydeepin/archive/2012/07/12/lombok.html
http://jnb.ociweb.com/jnb/jnbJan2010.html
lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码。
前置条件:
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:注解在类上;为类提供一个全参的构造方法
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:注解在类上
@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.
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.
@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.IllegalAccessException
would normally generate an "Unhandled exception" error if IllegalAccessException
, or some parent class, is not listed in a throws clause:@SneakyThrows
, the error goes away.@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.@SneakyThrows public void testSneakyThrows() { throw new IllegalAccessException(); }
public void testSneakyThrows() { try { throw new IllegalAccessException(); } catch (java.lang.Throwable $ex) { throw lombok.Lombok.sneakyThrow($ex); } }
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
Commons Codec 有许多针对 Base64 和 16 进制字符串的编码/解码方法。你就不要再浪费时间再去重新编写他们了。
Commons Lang 是针对 String 的创建和操作,字符集以及一堆实用工具方法的库。
Commons IO 拥有你可以想象得到的所有文件相关的方法。它有 FileUtils.copyDirectory,FileUtils.writeStringToFile,IOUtils.readLines 以及更多的东西。
Guava
Guava 是 Google 的优秀的补充Java所缺的库。几乎很难提交我所喜欢的有关于这个库的所每个功能,但我会试试。
Cache 是获取一个内存缓存的简单方法,可以被用来缓存网络访问,磁盘访问,记忆函数或者任何实在的数据。只要实现一个 CacheBuilder 就能告诉 Guava 如何去构建你的缓存,一切尽在你的掌握之中 !
我也喜欢用 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(); |
如果你还在 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
在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
他能让你用 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中单元测试的标准工具.
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" ); |
这样流畅的接口让你的测试更加可读. 夫复何求?
订阅:
博文 (Atom)