google / google/auto

Warn when an abstract type doesn't include a package-private constructor?

Open
#571 2 comments 2 reactions 0 assignees View on GitHub
P3
Dominant language
Java
Stars
10.6k
Forks
1.2k
Avg merge
6h 32m
Merged PRs (30d)
13

Description

Hello.

The documentation makes references here and there to an "immutability guarantee". However, if you write code as the documentation suggests:

```
@AutoValue
public abstract class T
{
public static T create(int x) { return AutoValue_T(x); }

public abstract int x();
}
```

The assumption then seems to be that you can write code that accepts values of type `T`, and that `T` is in some way guaranteed to be immutable.

The problem is that the above obviously exposes a default `public` constructor, which then means that anyone can subclass `T` (resulting in a type `U`), make it mutable, then pass values of `U` wherever `T` is expected. The obvious way to stop this:

```
@AutoValue
public abstract class T
{
T() { }

public static T create(int x) { return AutoValue_T(x); }

public abstract int x();
}
```

Now only code in the same package as `T` can subclass `T` (and let's assume that we can at least trust code within the same package not to abuse `T`!).

It would be really nice, given that I'm essentially going to be writing the above for every `@AutoValue` definition, if there was a way that the processor could warn me if I exposed a default public constructor. To some degree, `checkstyle` can do this, but not every project I work on is `checkstyle`-enabled. At the least, it might be worth mentioning in the documentation that exposing a constructor in this manner can lead to third party code subverting the "immutability guarantee" mentioned in the docs.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.