Skip to content

Added "Projects" under Resources in both the English and Chinese list #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 48 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

Java is one of the most popular programming languages around, but no one seems
to enjoy using it. Well, Java is actually an alright programming language, and
since Java 8 came out recently, I decided to compile a list of libraries,
since Java 8 came out recently, I decided to compile a list of libraries,
practices, and tools to make using Java better. "Better" is subjective, so I
would recommend taking the parts that speak to you and use them, rather than
trying to use all of them at once. Feel free to submit pull requests
trying to use all of them at once. Feel free to submit pull requests
suggesting additions.

This article was originally posted on
This article was originally posted on
[my blog](https://www.seancassidy.me/better-java.html).

Read this in other languages: [English](README.md), [简体中文](README.zh-cn.md)
Expand Down Expand Up @@ -64,6 +64,7 @@ Read this in other languages: [English](README.md), [简体中文](README.zh-cn.
* [Books](#books)
* [Podcasts](#podcasts)
* [Videos](#videos)
* [Projects](#projects)

## Style

Expand Down Expand Up @@ -112,7 +113,7 @@ is immutable unless you extend it, so we can reason about it easier as we know
that it can't be changed.

If you're storing objects like Map or List that can be modified easily, you
should instead use ImmutableMap or ImmutableList, which is discussed in the
should instead use ImmutableMap or ImmutableList, which is discussed in the
section about immutability.

#### The Builder Pattern
Expand All @@ -136,7 +137,7 @@ public class ComplicatedDataHolder {
public static class Builder {
private String data;
private int num;

public Builder data(String data) {
this.data = data;
return this;
Expand Down Expand Up @@ -166,31 +167,31 @@ final ComplicatedDataHolder cdh = new ComplicatedDataHolder.Builder()
There are [better examples of Builders elsewhere][builderex] but this should
give you a taste for what it's like. This ends up with a lot of the boilerplate
we were trying to avoid, but it gets you immutable objects and a very fluent
interface.
interface.

Instead of creating builder objects by hand, consider using one of the many
Instead of creating builder objects by hand, consider using one of the many
libraries which can help you generate builders.

#### Immutable Object Generation

If you create many immutable objects by hand, consider using the annotation
processor to generate them from interfaces automatically. This minimizes
If you create many immutable objects by hand, consider using the annotation
processor to generate them from interfaces automatically. This minimizes
boilerplate code, reduces probability of bugs and promotes immutability. See
this [presentation](https://docs.google.com/presentation/d/14u_h-lMn7f1rXE1nDiLX0azS3IkgjGl5uxp5jGJ75RE/edit#slide=id.g2a5e9c4a8_00)
for an interesting discussion of some of the problems with normal Java coding
patterns.

Some great code generation libraries are [immutables](https://github.com/immutables/immutables), Google's
[auto-value](https://github.com/google/auto/tree/master/value) and
Some great code generation libraries are [immutables](https://github.com/immutables/immutables), Google's
[auto-value](https://github.com/google/auto/tree/master/value) and
[Lombok][lombok].

### Exceptions

[Checked exceptions][checkedex] should be used with caution, if at all. They
force your users to add many try/catch blocks and wrap your exceptions in their
own. Better is to make your exceptions extend RuntimeException instead. This
allows your users to handle your exceptions in the way they would like, rather
than forcing them to handle/declare that it throws every time, which pollutes
[Checked exceptions][checkedex] should be used with caution, if at all. They
force your users to add many try/catch blocks and wrap your exceptions in their
own. Better is to make your exceptions extend RuntimeException instead. This
allows your users to handle your exceptions in the way they would like, rather
than forcing them to handle/declare that it throws every time, which pollutes
the code.

One nifty trick is to put RuntimeExceptions in your method's throws declaration.
Expand All @@ -205,27 +206,27 @@ the best ways to write testable software is to use [dependency injection][di]
you need to use DI.

In Java, this is typically done with the [Spring Framework][spring]. It has a
either code-based wiring or XML configuration-based wiring. If you use the XML
either code-based wiring or XML configuration-based wiring. If you use the XML
configuration, it's important that you [don't overuse Spring][springso] because
of its XML-based configuration format. There should be absolutely no logic or
control structures in XML. It should only inject dependencies.

Good alternatives to using Spring is Google and Square's [Dagger][dagger]
library or Google's [Guice][guice]. They don't use Spring's XML
library or Google's [Guice][guice]. They don't use Spring's XML
configuration file format, and instead they put the injection logic in
annotations and in code.

### Avoid Nulls

Try to avoid using nulls when you can. Do not return null collections when you
should have instead returned an empty collection. If you're going to use null,
consider the [@Nullable][nullable] annotation. [IntelliJ IDEA][intellij] has
should have instead returned an empty collection. If you're going to use null,
consider the [@Nullable][nullable] annotation. [IntelliJ IDEA][intellij] has
built-in support for the @Nullable annotation.

Read more about why not to use nulls in
[The worst mistake of computer science][the-worst-mistake-of-computer-science].

If you're using [Java 8][java8], you can use the excellent new
If you're using [Java 8][java8], you can use the excellent new
[Optional][optional] type. If a value may or may not be present, wrap it in
an *Optional* class like this:

Expand Down Expand Up @@ -297,7 +298,7 @@ Collections should, whenever possible, use the Guava
them up dynamically and then mark them immutable by calling the build method.

Classes should be made immutable by declaring fields immutable (via *final*)
and by using immutable collections. Optionally, you can make the class itself
and by using immutable collections. Optionally, you can make the class itself
*final* so that it can't be extended and made mutable.

### Avoid lots of Util classes
Expand All @@ -322,7 +323,7 @@ name of code reuse.

The cure is worse than the disease. Put these classes where they belong and
refactor aggressively. Don't name classes, packages, or libraries anything
too generic, such as "MiscUtils" or "ExtrasLibrary". This encourages dumping
too generic, such as "MiscUtils" or "ExtrasLibrary". This encourages dumping
unrelated code there.

### Formatting
Expand All @@ -338,7 +339,7 @@ If you absolutely need a code formatting guide, I highly recommend

#### Javadoc

Documenting your user facing code is important. And this means
Documenting your user facing code is important. And this means
[using examples][javadocex] and using sensible descriptions of variables,
methods, and classes.

Expand Down Expand Up @@ -382,10 +383,10 @@ flexible.

Because deploying Java isn't easy, frameworks have been made which can help.
Two of the best are [Dropwizard][dropwizard] and [Spring Boot][springboot].
The [Play framework][play] can also be considered one of these deployment
The [Play framework][play] can also be considered one of these deployment
frameworks as well.

All of them try to lower the barrier to getting your code out the door.
All of them try to lower the barrier to getting your code out the door.
They're especially helpful if you're new to Java or if you need to get things
done fast. Single JAR deployments are just easier than complicated WAR or EAR
deployments.
Expand All @@ -399,7 +400,7 @@ made, you'll have to migrate to a more hand-rolled configuration.
**Good alternative**: [Gradle][gradle].

Maven is still the standard tool to build, package, and run your tests. There
are alternatives, like Gradle, but they don't have the same adoption that Maven
are alternatives, like Gradle, but they don't have the same adoption that Maven
has. If you're new to Maven, you should start with
[Maven by Example][mavenexample].

Expand Down Expand Up @@ -446,7 +447,7 @@ is, something like this:

Which version will get pulled into your project?

With the [Maven dependency convergence plugin][depconverge], the build will
With the [Maven dependency convergence plugin][depconverge], the build will
error if your dependencies don't use the same version. Then, you have two
options for solving the conflict:

Expand All @@ -465,7 +466,7 @@ to continuously build your SNAPSHOT versions and tag builds based on git tags.

[Jenkins][jenkins] and [Travis-CI][travis] are natural choices.

Code coverage is useful, and [Cobertura][cobertura] has
Code coverage is useful, and [Cobertura][cobertura] has
[a good Maven plugin][coberturamaven] and CI support. There are other code
coverage tools for Java, but I've used Cobertura.

Expand All @@ -477,7 +478,7 @@ need a repository.
Common choices are [Artifactory][artifactory] and [Nexus][nexus]. Both work,
and have their own [pros and cons][mavenrepo].

You should have your own Artifactory/Nexus installation and
You should have your own Artifactory/Nexus installation and
[mirror your dependencies][artifactorymirror] onto it. This will stop your
build from breaking because some upstream Maven repository went down.

Expand All @@ -497,7 +498,7 @@ Regardless of what tool you choose, don't forget to automate your deployments.

## Libraries

Probably the best feature about Java is the extensive amount of libraries it
Probably the best feature about Java is the extensive amount of libraries it
has. This is a small collection of libraries that are likely to be applicable
to the largest group of people.

Expand All @@ -513,10 +514,10 @@ missing several key features.
**Commons Codec** has many useful encoding/decoding methods for Base64 and hex
strings. Don't waste your time rewriting those.

**Commons Lang** is the go-to library for String manipulation and creation,
**Commons Lang** is the go-to library for String manipulation and creation,
character sets, and a bunch of miscellaneous utility methods.

**Commons IO** has all the File related methods you could ever want. It has
**Commons IO** has all the File related methods you could ever want. It has
[FileUtils.copyDirectory][copydir], [FileUtils.writeStringToFile][writestring],
[IOUtils.readLines][readlines] and much more.

Expand Down Expand Up @@ -553,7 +554,7 @@ class, which has methods like filter and transform. They allow you to write
fluent code without [Java 8][java8]'s stream support.


Guava has simple things too, like a **Joiner** that joins strings on
Guava has simple things too, like a **Joiner** that joins strings on
separators and a [class to handle interrupts][uninterrupt] by ignoring them.

#### Gson
Expand Down Expand Up @@ -627,9 +628,9 @@ public static List<String> sayByeBye() {
#### Joda-Time

[Joda-Time][joda] is easily the best time library I've ever used. Simple,
straightforward, easy to test. What else can you ask for?
straightforward, easy to test. What else can you ask for?

You only need this if you're not yet on Java 8, as that has its own new
You only need this if you're not yet on Java 8, as that has its own new
[time][java8datetime] library that doesn't suck.

#### Lombok
Expand Down Expand Up @@ -659,20 +660,20 @@ yet, but I can't wait to.

**Good alternatives**: [Jersey][jersey] or [Spark][spark]

There are two main camps for doing RESTful web services in Java:
There are two main camps for doing RESTful web services in Java:
[JAX-RS][jaxrs] and everything else.

JAX-RS is the traditional way. You combine annotations with interfaces and
implementations to form the web service using something like [Jersey][jersey].
What's nice about this is you can easily make clients out of just the
What's nice about this is you can easily make clients out of just the
interface class.

The [Play framework][play] is a radically different take on web services on
the JVM: you have a routes file and then you write the classes referenced in
those routes. It's actually an [entire MVC framework][playdoc], but you can
easily use it for just REST web services.

It's available for both Java and Scala. It suffers slightly from being
It's available for both Java and Scala. It suffers slightly from being
Scala-first, but it's still good to use in Java.

If you're used to micro-frameworks like Flask in Python, [Spark][spark] will
Expand All @@ -698,7 +699,7 @@ It lets you write SQL in Java in a type safe way:

```java
// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
Result<Record3<String, String, String>> result =
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
Expand Down Expand Up @@ -740,7 +741,7 @@ public class FooWidgetTest {
@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();
Expand Down Expand Up @@ -793,7 +794,7 @@ This fluent interface makes your tests more readable. What more could you want?

The best Java IDE is [IntelliJ IDEA][intellij]. It has a ton of awesome
features, and is really the main thing that makes the verbosity of Java
bareable. Autocomplete is great,
bareable. Autocomplete is great,
[the inspections are top notch][intellijexample], and the refactoring
tools are really helpful.

Expand Down Expand Up @@ -830,7 +831,7 @@ and Strings that are actually regular expressions, nor does it do any
[taint checking][taint]. However, [the Checker Framework][checker]
does this and more.

It uses annotations like *@Nullable* to check types. You can even define
It uses annotations like *@Nullable* to check types. You can even define
[your own annotations][customchecker] to make the static analysis done even
more powerful.

Expand Down Expand Up @@ -912,6 +913,10 @@ Resources to help you become a Java master.
* [InfoQ](http://www.infoq.com/) - see especially [presentations](http://www.infoq.com/java/presentations/) and [interviews](http://www.infoq.com/java/interviews/)
* [Parleys](https://www.parleys.com/)

### Projects

* [DevProjects - Real-world projects to learn Java](https://www.codementor.io/projects/java)

[immutablemap]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html
[immutablelist]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableList.html
[immutableset]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableSet.html
Expand Down
18 changes: 10 additions & 8 deletions README.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Java 虽作为最流行的编程语言之一,但是似乎并没有什么人很享受用它。好吧,Java 确实是这样的一门编程语言,从最近发布不久的 Java 8 开始,为了更好的使用 Java,我决定收集一些库,实践和工具等相关资料。“更好” 是主观的,所以推荐使用我所说的建议的某些部分,而不是一下子全部按照这些建议来做。请尽情添加其他意见并提交 PR。

这篇文章原始发布在
这篇文章原始发布在
[我的博客](https://www.seancassidy.me/better-java.html).

其他语言版本: [English](README.md), [简体中文](README.zh-cn.md)
Expand Down Expand Up @@ -55,6 +55,7 @@ Java 虽作为最流行的编程语言之一,但是似乎并没有什么人很
* [Books(书)](#books)
* [Podcasts(播客)](#podcasts)
* [Videos(视频)](#videos)
* [Projects (业余项目)](#projects)

## Style

Expand Down Expand Up @@ -116,7 +117,7 @@ public class ComplicatedDataHolder {
public static class Builder {
private String data;
private int num;

public Builder data(String data) {
this.data = data;
return this;
Expand Down Expand Up @@ -153,7 +154,7 @@ final ComplicatedDataHolder cdh = new ComplicatedDataHolder.Builder()

一些非常棒的代码生成库如 [immutables]
(https://github.com/immutables/immutables), 谷歌的
[auto-value](https://github.com/google/auto/tree/master/value) 和
[auto-value](https://github.com/google/auto/tree/master/value) 和
[Lombok][lombok]

### Exceptions
Expand Down Expand Up @@ -352,7 +353,7 @@ Java 最好的一方面就是拥有大量的第三方库可以做任何事。基

[Jenkins][jenkins] 和 [Travis-CI][travis] 就成了很自然的选择.

代码覆盖率非常有用,[Cobertura][cobertura] 就有 [一个很好的 Maven 插件][coberturamaven]
代码覆盖率非常有用,[Cobertura][cobertura] 就有 [一个很好的 Maven 插件][coberturamaven]
[a good Maven plugin][coberturamaven] 并且支持 CI。还有一些其他的支持 Java 的代码覆盖率工具,但是我只用过 Cobertura。

### Maven repository
Expand Down Expand Up @@ -528,7 +529,7 @@ JAX-RS 是传统的实现方式。你可以用像 [Jersey][jersey] 这样的框

```java
// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
Result<Record3<String, String, String>> result =
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
Expand Down Expand Up @@ -564,7 +565,7 @@ public class FooWidgetTest {
@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();
Expand Down Expand Up @@ -689,6 +690,9 @@ Heap dump file created
* [InfoQ](http://www.infoq.com/) - see especially [presentations](http://www.infoq.com/java/presentations/) and [interviews](http://www.infoq.com/java/interviews/)
* [Parleys](https://www.parleys.com/)

### Projects
* [DevProjects - 透过实际项目学习 Java](https://www.codementor.io/projects/java)

[immutablemap]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html
[immutablelist]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableList.html
[immutableset]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableSet.html
Expand Down Expand Up @@ -777,5 +781,3 @@ Heap dump file created
[java8datetime]: http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html
[checkedex]: http://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html
[the-worst-mistake-of-computer-science]: https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/