{"id":13485583,"url":"https://github.com/inferred/FreeBuilder","last_synced_at":"2025-03-27T19:31:29.120Z","repository":{"id":636265,"uuid":"28824978","full_name":"inferred/FreeBuilder","owner":"inferred","description":"Automatic generation of the Builder pattern for Java","archived":true,"fork":false,"pushed_at":"2024-10-16T08:44:55.000Z","size":4728,"stargazers_count":834,"open_issues_count":50,"forks_count":101,"subscribers_count":43,"default_branch":"main","last_synced_at":"2025-01-08T04:02:03.778Z","etag":null,"topics":["builder-pattern","code-generator","java"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inferred.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-01-05T18:11:27.000Z","updated_at":"2024-12-21T15:51:12.000Z","dependencies_parsed_at":"2024-01-03T01:20:51.743Z","dependency_job_id":"803a876a-6df4-48dd-8390-9b3881ab41d5","html_url":"https://github.com/inferred/FreeBuilder","commit_stats":{"total_commits":736,"total_committers":14,"mean_commits":52.57142857142857,"dds":0.5230978260869565,"last_synced_commit":"3a38f58e1e5e69f4b71bd8ac4c5dcfc4c37fa587"},"previous_names":["google/freebuilder"],"tags_count":89,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inferred%2FFreeBuilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inferred%2FFreeBuilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inferred%2FFreeBuilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inferred%2FFreeBuilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inferred","download_url":"https://codeload.github.com/inferred/FreeBuilder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245910811,"owners_count":20692505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["builder-pattern","code-generator","java"],"created_at":"2024-07-31T18:00:26.995Z","updated_at":"2025-03-27T19:31:28.533Z","avatar_url":"https://github.com/inferred.png","language":"Java","readme":"FreeBuilder\n===========\n\n_Automatic generation of the Builder pattern for Java 1.8+_\n\n[![Maven Central](https://img.shields.io/maven-central/v/org.inferred/freebuilder.svg)](https://search.maven.org/artifact/org.inferred/freebuilder)\n[![CI (GitHub Workflow)](https://github.com/inferred/FreeBuilder/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/inferred/FreeBuilder/actions/workflows/ci.yml?query=branch%3Amain)\n\n\u003e The Builder pattern is a good choice when designing classes whose constructors\n\u003e or static factories would have more than a handful of parameters.\n\u003e \u0026mdash; \u003cem\u003eEffective Java, Second Edition\u003c/em\u003e, page 39\n\nProject Archival\n----------------\n\nFreeBuilder was released back in 2015! It was a pet project of my own that unfortunately generated a weird amount of controversy at the company I worked at at the time, and thus ended up being open-sourced after the Immutables project had already been on the scene for most of a year. While I hoped the different design that allowed using partials for robust testing would still be a winner, a community hasn't picked up, and as I haven't used Java at my work for over 5 years now, and it's clearly not keeping up with modern Java, I think it's time to archive it.\n\nIf someone feels strongly about picking up where I've left off, please do reach out and let me know! I'd ask that you first fork the project and modernize the dev and CI setup, which really needs doing.\n\nOtherwise, it's been a fun ride, and thanks to everyone who's been building free with me along the way 😁\n\n\u0026mdash; Alice\n\nTable of Contents\n-----------------\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Project Archival](#project-archival)\n- [Background](#background)\n- [How to use FreeBuilder](#how-to-use-freebuilder)\n  - [Quick start](#quick-start)\n  - [What you get](#what-you-get)\n  - [Accessor methods](#accessor-methods)\n  - [Defaults and constraints](#defaults-and-constraints)\n  - [Optional values](#optional-values)\n    - [Using `@Nullable`](#using-nullable)\n    - [Converting from `@Nullable`](#converting-from-nullable)\n  - [Collections and Maps](#collections-and-maps)\n  - [Nested buildable types](#nested-buildable-types)\n  - [Lists of buildable types](#lists-of-buildable-types)\n    - [Disabling buildable lists](#disabling-buildable-lists)\n  - [Custom toString method](#custom-tostring-method)\n  - [Custom conventional method names](#custom-conventional-method-names)\n  - [Custom functional interfaces](#custom-functional-interfaces)\n  - [Builder construction](#builder-construction)\n  - [Partials](#partials)\n  - [Jackson](#jackson)\n  - [GWT](#gwt)\n- [Build tools and IDEs](#build-tools-and-ides)\n  - [javac](#javac)\n  - [Maven](#maven)\n  - [Gradle](#gradle)\n  - [Eclipse](#eclipse)\n  - [IntelliJ](#intellij)\n- [Release notes](#release-notes)\n  - [2.3—From method testability](#23from-method-testability)\n  - [2.2—Primitive optional types](#22primitive-optional-types)\n  - [2.1—Lists of buildable types](#21lists-of-buildable-types)\n  - [Upgrading from v1](#upgrading-from-v1)\n- [Troubleshooting](#troubleshooting)\n  - [Troubleshooting javac](#troubleshooting-javac)\n  - [Troubleshooting Eclipse](#troubleshooting-eclipse)\n  - [Online resouces](#online-resouces)\n- [Alternatives](#alternatives)\n  - [Immutables vs FreeBuilder](#immutables-vs-freebuilder)\n  - [AutoValue vs FreeBuilder](#autovalue-vs-freebuilder)\n  - [Proto vs FreeBuilder](#proto-vs-freebuilder)\n- [Wait, why \"free\"?](#wait-why-free)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n\nBackground\n----------\n\nImplementing the [Builder pattern](http://en.wikipedia.org/wiki/Builder_pattern)\nin Java is tedious, error-prone and repetitive. Who hasn't seen a ten-argument\nconstructor, thought cross thoughts about the previous maintainers of the\nclass, then added \"just one more\"? Even a simple four-field class requires 39\nlines of code for the most basic builder API, or 72 lines if you don't use a\nutility like [AutoValue][] to generate the value boilerplate.\n\nFreeBuilder produces all the boilerplate for you, as well as free extras like\nJavaDoc, getter methods, mapper methods, [collections support](#collections-and-maps),\n[nested builders](#nested-buildable-types), and [partial values](#partials)\n(used in testing), which are highly useful, but would very rarely justify\ntheir creation and maintenance burden in hand-crafted code. (We also reserve\nthe right to add more awesome methods in future!)\n\n\n\u003e [The Builder pattern] is more verbose\u0026#8230;so should only be used if there are\n\u003e enough parameters, say, four or more. But keep in mind that you may want to add\n\u003e parameters in the future. If you start out with constructors or static\n\u003e factories, and add a builder when the class evolves to the point where the\n\u003e number of parameters starts to get out of hand, the obsolete constructors or\n\u003e static factories will stick out like a sore thumb. Therefore, it's often better\n\u003e to start with a builder in the first place.\n\u003e \u0026mdash; \u003cem\u003eEffective Java, Second Edition\u003c/em\u003e, page 39\n\n\nHow to use FreeBuilder\n----------------------\n\n\n### Quick start\n\n_See [Build tools and IDEs](#build-tools-and-ides) for how to add FreeBuilder \nto your project's build and/or IDE._\n\nCreate your value type (e.g. `Person`) as an interface or abstract class,\ncontaining an abstract accessor method for each desired field. Add the\n`@FreeBuilder` annotation to your class, and it will automatically generate an\nimplementing class and a package-visible builder API (`Person_Builder`), which\nyou must subclass. For instance:\n\n\n```java\nimport org.inferred.freebuilder.FreeBuilder;\n\n@FreeBuilder\npublic interface Person {\n  /** Returns this person's full (English) name. */\n  String name();\n  /** Returns this person's age in years, rounded down. */\n  int age();\n  /** Returns a new {@link Builder} with the same property values as this person. */\n  Builder toBuilder();\n  /** Builder of {@link Person} instances. */\n  class Builder extends Person_Builder { }\n}\n```\n\nThe `toBuilder()` method here is optional but highly recommended.\nYou may also wish to make the builder's constructor package-protected and manually\nprovide instead a static `builder()` method on the value type (though\n\u003cem\u003eEffective Java\u003c/em\u003e does not do this).\n\n\n### What you get\n\nIf you write the Person interface shown above, you get:\n\n  * A builder class with:\n     * a no-args constructor\n     * JavaDoc\n     * getters (throwing `IllegalStateException` for unset fields)\n     * setters\n     * lambda-accepting mapper methods\n     * `mergeFrom` and static `from` methods to copy data from existing values or builders\n     * a `build` method that verifies all fields have been set\n        * [see below for default values and constraint checking](#defaults-and-constraints)\n  * An implementation of `Person` with:\n     * `toString`\n     * `equals` and `hashCode`\n  * A [partial](#partials) implementation of `Person` for unit tests with:\n     * `UnsupportedOperationException`-throwing getters for unset fields\n     * `toString`\n     * `equals` and `hashCode`\n\n\n```java\nPerson person = new Person.Builder()\n    .name(\"Phil\")\n    .age(31)\n    .build();\nSystem.out.println(person);  // Person{name=Phil, age=31}\n```\n\n\n### JavaBean convention\n\nIf you prefer your value types to follow the JavaBean naming convention, just prefix your accessor methods with 'get' (or, optionally, 'is' for boolean accessors). FreeBuilder will follow suit, and additionally add 'set' prefixes on setter methods, as well as dropping the prefix from its toString output.\n\n```java\n@FreeBuilder\npublic interface Person {\n  /** Returns the person's full (English) name. */\n  String getName();\n  /** Returns the person's age in years, rounded down. */\n  int getAge();\n  /** Builder of {@link Person} instances. */\n  class Builder extends Person_Builder { }\n}\n\nPerson person = new Person.Builder()\n    .setName(\"Phil\")\n    .setAge(31)\n    .build();\nSystem.out.println(person);  // Person{name=Phil, age=31}\n```\n\n\n### Accessor methods\n\nFor each property `foo`, the builder gets:\n\n| Method | Description |\n|:------:| ----------- |\n| A setter method, `foo` | Throws a NullPointerException if provided a null. (See the sections on [Optional](#optional-values) and [Nullable](#using-nullable) for ways to store properties that can be missing.) |\n| A getter method, `foo` | Throws an IllegalStateException if the property value has not yet been set. |\n| A mapper method, `mapFoo` | Takes a [UnaryOperator]. Replaces the current property value with the result of invoking the unary operator on it. Throws a NullPointerException if the operator, or the value it returns, is null. Throws an IllegalStateException if the property value has not yet been set. |\n\nThe mapper methods are very useful when modifying existing values, e.g.\n\n```java\nPerson olderPerson = person.toBuilder().mapAge(age -\u003e age + 1).build();\n```\n\n[UnaryOperator]: https://docs.oracle.com/javase/8/docs/api/java/util/function/UnaryOperator.html\n\n\n### Defaults and constraints\n\nWe use method overrides to add customization like default values and constraint\nchecks. For instance:\n\n\n```java\n@FreeBuilder\npublic interface Person {\n  /** Returns the person's full (English) name. */\n  String name();\n  /** Returns the person's age in years, rounded down. */\n  int age();\n  /** Returns a human-readable description of the person. */\n  String description();\n  /** Builder class for {@link Person}. */\n  class Builder extends Person_Builder {\n    public Builder() {\n      // Set defaults in the builder constructor.\n      description(\"Indescribable\");\n    }\n    @Override Builder age(int age) {\n      // Check single-field (argument) constraints in the setter method.\n      checkArgument(age \u003e= 0);\n      return super.age(age);\n    }\n    @Override public Person build() {\n      // Check cross-field (state) constraints in the build method.\n      Person person = super.build();\n      checkState(!person.description().contains(person.name()));\n      return person;\n    }\n  }\n}\n```\n\n\n### Optional values\n\nIf a property is optional\u0026mdash;that is, has no reasonable default\u0026mdash;then\nuse [the Java Optional type][] (or [the Guava Optional type][] for\nbackwards-compatibility).\n\n[the Java Optional type]: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html\n[the Guava Optional type]: http://google.github.io/guava/releases/19.0/api/docs/com/google/common/base/Optional.html\n\n\n```java\n  /** Returns an optional human-readable description of the person. */\n  Optional\u003cString\u003e description();\n```\n\nThis property will now default to Optional.empty(), and the Builder\nwill gain additional convenience setter methods:\n\n| Method | Description |\n|:------:| ----------- |\n| `description(String value)` | Sets the property to `Optional.of(value)`. Throws a NullPointerException if value is null; this avoids users accidentally clearing an optional value in a way that peer review is unlikely to catch. |\n| `clearDescription()` | Sets the property to `Optional.empty()`. |\n| `description(Optional\u003cString\u003e value)` | Sets the property to `value`. |\n| `nullableDescription(String value)` | Sets the property to `Optional.ofNullable(value)`. |\n| `mapDescription(UnaryOperator\u003cString\u003e mapper` | If the property value is not empty, this replaces the value with the result of invoking `mapper` with the existing value, or clears it if `mapper` returns null. Throws a NullPointerException if `mapper` is null. |\n\nPrefer to use explicit defaults where meaningful, as it avoids the need for\nedge-case code; but prefer Optional to ad-hoc 'not set' defaults, like -1 or\nthe empty string, as it forces the user to think about those edge cases.\n\n#### Using `@Nullable`\n\nAs Java currently stands, **you should strongly prefer Optional to returning\nnulls**. Using null to represent unset properties is the classic example of\n[Hoare's billion-dollar mistake][Hoare]: a silent source of errors that users\nwon't remember to write test cases for, and which won't be spotted in code reviews.\nThe large \"air gap\" between the declaration of the getter and the usage is the\ncause of this problem. Optional uses the compiler to force the call sites to\nperform explicit null handling, giving reviewers a better chance of seeing\nmistakes. See also [Using and Avoiding Null][].\n\nObviously, greenfield code can trivially adopt Optional, but even existing APIs\ncan be converted to Optional via a simple refactoring sequence; see below.\nHowever, if you have **compelling legacy reasons** that mandate using nulls,\nyou can disable null-checking by marking the getter method `@Nullable`. (Any\nannotation type named \"Nullable\" will do, but you may wish to use\n`javax.annotation.Nullable`, as used in [Google Guava][Guava].)\n\n```java\n  /** Returns an optional title to use when addressing the person. */\n  @Nullable String title();\n```\n\nThis property will now default to null, and the Builder's setter methods will\nchange their null-handling behaviour:\n\n| Method | Description |\n|:------:| ----------- |\n| `title(@Nullable String title)` | Sets the property to `title`. |\n| `title()` | Returns the current value of the property. May be null. |\n| `mapTitle(UnaryOperator\u003cString\u003e mapper)` | Takes a [UnaryOperator]. Replaces the current property value, if it is not null, with the result of invoking `mapper` on it. Throws a NullPointerException if `mapper` is null. `mapper` may return a null. |\n\n[Guava]: https://github.com/google/guava\n[Hoare]: http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare\n[Using and Avoiding Null]: https://github.com/google/guava/wiki/UsingAndAvoidingNullExplained\n\n#### Converting from `@Nullable`\n\nThis is the O(1), non-tedious, non\u0026ndash;error-prone way we recomment converting\n`@Nullable` to Optional:\n\n * Load all your code in Eclipse, or another IDE with support for renaming and\n    inlining.\n * _[IDE REFACTOR]_ Rename all your `@Nullable` getters to `nullableX()` (or `getNullableX()` if you use JavaBean naming conventions).\n * Add an Optional-returning `x()` (or `getX()`)\n * Implement your nullableX methods as:  `return x().orElse(null)`\n   \u003cbr\u003e(Guava: `return x().orNull()`)\n * _[IDE REFACTOR]_ Inline your `nullableX()` methods\n\nAt this point, you have effectively performed an automatic translation of a\n`@Nullable` method to an Optional-returning one. Of course, your code is not\noptimal yet (e.g.  `if (foo.x().orElse(null) != null)`  instead of  `if\n(foo.x().isPresent())` ). Search-and-replace should get most of these issues.\n\n * _[IDE REFACTOR]_ Rename all your `@Nullable` setters to `nullableX` (or `setNullableX`).\n\nYour API is now FreeBuilder-compatible :)\n\n\n### Collections and Maps\n\nFreeBuilder has special support for collection and map properties, removing\nthe `foo` accessor method and generating new ones appropriate to the type.\nCollection and map properties default to an empty collection/map and cannot hold\nnulls.\n\n```java\n  /** Returns a list of descendents for this person. **/\n  List\u003cString\u003e descendants();\n```\n\nA \u003ccode\u003e[List][]\u003c/code\u003e, \u003ccode\u003e[Set][]\u003c/code\u003e, \u003ccode\u003e[SortedSet][]\u003c/code\u003e or \u003ccode\u003e[Multiset][]\u003c/code\u003e\nproperty called 'descendants' would generate:\n\n| Method | Description |\n|:------:| ----------- |\n| `addDescendants(String element)` | Appends `element` to the collection of descendants. If descendants is a set and the element is already present, it is ignored. Throws a NullPointerException if element is null. |\n| `addDescendants(String... elements)` | Appends all `elements` to the collection of descendants. If descendants is a set, any elements already present are ignored. Throws a NullPointerException if elements, or any of the values it holds, is null. |\n| `addAllDescendants(​Iterable\u003cString\u003e elements)`\u003cbr\u003e`addAllDescendants(​Stream\u003cString\u003e elements)`\u003cbr\u003e`addAllDescendants(​Spliterator\u003cString\u003e elements)` | Appends all `elements` to the collection of descendants. If descendants is a set, any elements already present are ignored. Throws a NullPointerException if elements, or any of the values it holds, is null. |\n| `mutateDescendants(​Consumer\u003c‌.‌.‌.‌\u003cString\u003e\u003e mutator)` | Invokes the [Consumer] `mutator` with the collection of descendants. (The mutator takes a list, set or map as appropriate.) Throws a NullPointerException if `mutator` is null. As `mutator` is a void consumer, any value returned from a lambda will be ignored, so be careful not to call pure functions like [stream()] expecting the returned collection to replace the existing collection. |\n| `clearDescendants()` | Removes all elements from the collection of descendants, leaving it empty. |\n| `descendants()` | Returns an unmodifiable view of the collection of descendants. Changes to the collection held by the builder will be reflected in the view. |\n| `setComparatorForDescendants(​Comparator\u003c? super String\u003e comparator)` | *SortedSet only* A protected method that sets the [comparator] to keep the set elements ordered by. Must be called before any other accessor method for this property. Defaults to the [natural ordering] of the set's elements. |\n\n```java\n  /** Returns a map of favourite albums by year. **/\n  Map\u003cInteger, String\u003e albums();\n```\n\nA \u003ccode\u003e[Map][]\u003c/code\u003e property called 'albums' would generate:\n\n| Method | Description |\n|:------:| ----------- |\n| `putAlbums(int key, String value)` | Associates `key` with `value` in albums.  Throws a NullPointerException if either parameter is null. Replaces any existing entry. |\n| `putAllAlbums(Map\u003c? extends Integer, ? extends String\u003e map)` | Associates all of `map`'s keys and values in albums. Throws a NullPointerException if the map is null or contains a null key or value. Replaces any existing mapping for all keys in `map`. |\n| `removeAlbums(int key)` | Removes the mapping for `key` from albums. Throws a NullPointerException if the parameter is null. Does nothing if the key is not present. |\n| `mutateAlbums(​Consumer\u003cMap\u003cInteger, String\u003e\u003e mutator)` | Invokes the [Consumer] `mutator` with the map of albums. Throws a NullPointerException if `mutator` is null. As `mutator` is a void consumer, any value returned from a lambda will be ignored, so be careful not to call pure functions like [stream()] expecting the returned map to replace the existing map. |\n| `clearAlbums()` | Removes all mappings from albums, leaving it empty. |\n| `albums()` | Returns an unmodifiable view of the map of albums. Changes to the map held by the builder will be reflected in this view. |\n\n```java\n  /** Returns a bimap of favourite albums by year. **/\n  BiMap\u003cInteger, String\u003e albums();\n```\n\nA \u003ccode\u003e[BiMap][]\u003c/code\u003e property called 'albums' would generate:\n\n| Method | Description |\n|:------:| ----------- |\n| `putAlbums(int key, String value)` | Associates `key` with `value` in albums.  Throws a NullPointerException if either parameter is null, or an IllegalArgumentException if `value` is already bound to a different key. Replaces any existing entry for `key`. |\n| `forcePutAlbums(int key, String value)` | Associates `key` with `value` in albums.  Throws a NullPointerException if either parameter is null. Replaces any existing entry for both `key` _and_ `value`. _Override this method to implement [constraint checks](#defaults-and-constraints)._ |\n| `putAllAlbums(Map\u003c? extends Integer, ? extends String\u003e map)` | Associates all of `map`'s keys and values in albums. Throws a NullPointerException if the map is null or contains a null key or value. Replaces any existing mapping for all keys in `map`. Throws an IllegalArgumentException if an attempt to put any entry fails. |\n| `removeKeyFromAlbums(int key)` | Removes the mapping for `key` from albums. Throws a NullPointerException if the parameter is null. Does nothing if the key is not present. |\n| `removeValueFromAlbums(String value)` | Removes the mapping for `value` from albums. Throws a NullPointerException if the parameter is null. Does nothing if the value is not present. |\n| `mutateAlbums(​Consumer\u003cBiMap\u003cInteger, String\u003e\u003e mutator)` | Invokes the [Consumer] `mutator` with the bimap of albums. Throws a NullPointerException if `mutator` is null. As `mutator` is a void consumer, any value returned from a lambda will be ignored, so be careful not to call pure functions like [stream()] expecting the returned map to replace the existing map. |\n| `clearAlbums()` | Removes all mappings from albums, leaving it empty. |\n| `albums()` | Returns an unmodifiable view of the bimap of albums. Changes to the bimap held by the builder will be reflected in this view. |\n\n```java\n  /** Returns a multimap of all awards by year. **/\n  SetMultimap\u003cInteger, String\u003e awards();\n```\n\nA \u003ccode\u003e[Multimap][]\u003c/code\u003e property called 'awards' would generate:\n\n| Method | Description |\n|:------:| ----------- |\n| `putAwards(int key, String value)` | Associates `key` with `value` in awards. Throws a NullPointerException if either parameter is null. |\n| `putAllAwards(int key, Iterable\u003c? extends String\u003e values)` | Associates `key` with every element of `values` in awards. Throws a NullPointerException if either parameter, or any value, is null. |\n| `putAllAwards(Map\u003c? extends Integer, ? extends String\u003e map)` | Associates all of `map`'s keys and values in awards. Throws a NullPointerException if the map is null or contains a null key or value. If awards is a map, an IllegalArgumentException will be thrown if any key is already present. |\n| `removeAwards(int key, String value)` | Removes the single pair `key`-`value` from awards. If multiple pairs match, which is removed is unspecified. Throws a NullPointerException if either parameter is null. |\n| `removeAllAwards(int key)` | Removes all values associated with `key` from awards. Throws a NullPointerException if the key is null. |\n| `mutateAwards(​Consumer\u003cMap\u003cInteger, String\u003e\u003e mutator)` | Invokes the [Consumer] `mutator` with the multimap of awards. Throws a NullPointerException if `mutator` is null. As `mutator` is a void consumer, any value returned from a lambda will be ignored, so be careful not to call pure functions like [stream()] expecting the returned multimap to replace the existing multimap. |\n| `clearAwards()` | Removes all mappings from awards, leaving it empty. |\n| `awards()` | Returns an unmodifiable view of the multimap of awards. Changes to the multimap held by the builder will be reflected in this view. |\n\nIn all cases, the value type will return immutable objects from its getter.\n\nThe mutator methods are useful for invoking methods not directly exposed on the builder, like [subList], or methods that take a mutable collection, like [sort]:\n\n```java\npersonBuilder\n    // Delete the fourth and fifth descendants in the list\n    .mutateDescendants(d -\u003e d.subList(3,5).clear())\n    // Sort the remaining descendants\n    .mutateDescendants(Collections::sort);\n```\n\n[Comparator]: https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html\n[List]: http://docs.oracle.com/javase/tutorial/collections/interfaces/list.html\n[Set]: http://docs.oracle.com/javase/tutorial/collections/interfaces/set.html\n[SortedSet]: http://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html\n[Spliterator]: https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html\n[Stream]: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html\n[Multiset]: https://github.com/google/guava/wiki/NewCollectionTypesExplained#multiset\n[Map]: http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html\n[BiMap]: https://github.com/google/guava/wiki/NewCollectionTypesExplained#bimap\n[Multimap]: https://github.com/google/guava/wiki/NewCollectionTypesExplained#multimap\n[natural ordering]: https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html\n[sort]: http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-\n[stream()]: https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#stream--\n[subList]: http://docs.oracle.com/javase/8/docs/api/java/util/List.html#subList-int-int-\n\n\n### Nested buildable types\n\n```java\n  /** Returns the person responsible for this project. */\n  Person owner();\n```\n\nFreeBuilder has special support for buildable types like [protos][] and other\nFreeBuilder types. A buildable property called 'owner' would generate:\n\n| Method | Description |\n|:------:| ----------- |\n| `owner(Person owner)` | Sets the owner. Throws a NullPointerException if provided a null. |\n| `owner(Person.Builder builder)` | Calls `build()` on `builder` and sets the owner to the result. Throws a NullPointerException if builder or the result of calling `build()` is null. |\n| `ownerBuilder()` | Returns a builder for the owner property. Unlike other getter methods in FreeBuilder-generated API, this object is mutable, and modifying it **will modify the underlying property**. |\n| `mutateOwner(Consumer\u003cPerson.Builder\u003e mutator)` | Invokes the [Consumer] `mutator` with the builder for the property. Throws a NullPointerException if `mutator` is null. As `mutator` is a void consumer, any value returned from a lambda will be ignored. |\n\nThe mutate method allows the buildable property to be set up or modified succinctly and readably:\n\n```java\nProject project = new Project.Builder()\n    .mutateOwner($ -\u003e $\n        .name(\"Phil\")\n        .department(\"HR\"))\n    .build();\n```\n\n[protos]: https://developers.google.com/protocol-buffers/\n[Consumer]: https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html\n\n\n### Lists of buildable types\n\nFreeBuilder has special support for lists of buildable types, too. It maintains\na list of builders, to allow elements of the list to be built incrementally. (For\nbetter performance, if given a built instance for the list, it will lazily convert\nit to a Builder on demand. This may cause problems if your buildable types\ncontinue to be mutable after construction; to avoid unpredictable aliasing,\nwe recommend disabling buildable list support, as described below.)\n\nA list of buildable properties called 'owners' would generate:\n\n| Method | Description |\n|:------:| ----------- |\n| `addOwners(Person element)` | Appends `element` to the collection of owners. Throws a NullPointerException if element is null. The element may be lazily converted to/from a Builder. |\n| `addOwners(Person.Builder builder)` | Appends the value built by `builder` to the collection of owners. Throws a NullPointerException if builder is null. Only a copy of the builder will be stored; changes made to it after this method returns will have no effect on the list. The copied builder's `build()` method will not be called immediately, so if this builder's state is not legal, you will not get failures until you build the final immutable object. |\n| `addOwners(Person... elements)` | Appends all `elements` to the collection of owners.  Throws a NullPointerException if elements, or any of the values it holds, is null. Each element may be lazily converted to/from a Builder. |\n| `addOwners(Person.Builder... builders)` | Appends the values built by `builders` to the collection of owners.  Throws a NullPointerException if builders, or any of the values it holds, is null. Only copies of the builders will be stored, and `build()` methods will not be called immediately. |\n| `addAllOwners(​Iterable\u003cPerson\u003e elements)`\u003cbr\u003e`addAllOwners(​Stream\u003cPerson\u003e elements)`\u003cbr\u003e`addAllOwners(​Spliterator\u003cPerson\u003e elements)` | Appends all `elements` to the collection of owners.  Throws a NullPointerException if elements, or any of the values it holds, is null. Each element may be lazily converted to/from a Builder. |\n| `addAllBuildersOfOwners(​Iterable\u003cPerson.Builder\u003e builders)`\u003cbr\u003e`addAllBuildersOfOwners(​Stream\u003cPerson.Builder\u003e builders)`\u003cbr\u003e`addAllBuildersOfOwners(​Spliterator\u003cPerson.Builder\u003e builders)` | Appends the values built by `builders` to the collection of owners.  Throws a NullPointerException if builders, or any of the values it holds, is null. Only copies of the builders will be stored, and `build()` methods will not be called immediately. |\n| `mutateOwners(​Consumer\u003c? super List\u003cPerson.Builder\u003e\u003e mutator)` | Invokes the [Consumer] `mutator` with the list of owner builders. Throws a NullPointerException if `mutator` is null. As `mutator` is a void consumer, any value returned from a lambda will be ignored, so be careful not to call pure functions like [stream()] expecting the returned collection to replace the existing collection. |\n| `clearOwners()` | Removes all elements from the collection of owners, leaving it empty. |\n| `buildersOfOwners()` | Returns an unmodifiable view of the list of owner builders. Changes to the list held by the builder will be reflected in the view, and changes made to any of the returned builders will be reflected in the final list of owners. |\n\nNote that `mutateOwners` and `buildersOfOwners` are the only methods which can cause lazy convertion of an inserted value to a Builder, and then only upon accessing the element, so avoid these actions if possible to avoid unexpected performance hits.\n\n#### Disabling buildable lists\n\nYou can force FreeBuilder to use vanilla list support, rather than converting elements\nto/from Builders under the hood, by declaring a vanilla getter in the Builder. For\ninstance, to force `owners` to drop Builder support:\n\n```java\n  class Builder extends Foo_Builder {\n    @Override\n    public List\u003cPerson\u003e owners() {\n      // Disable FreeBuilder's lazy conversion to/from Person.Builder by declaring\n      // a non-Builder-compatible getter.\n      return super.owners();\n    }\n  }\n```\n\nFreeBuilder will now generate the methods described in [Collections and Maps](#collections-and-maps).\n\n\n### Custom toString method\n\nFreeBuilder will only generate toString, hashCode and equals methods if they are left abstract, so to customise them, just implement them.\n(Due to language constraints, you will need to first convert your type to an abstract class if it was previously an interface.)\n\n```java\nabstract class Person {\n  public abstract String name();\n  public abstract int age();\n\n  @Override public String toString() {\n    return name() + \" (\" + age() + \" years old)\";\n  }\n\n  public static class Builder extends Person_Builder {}\n}\n```\n\nNote that it is a compile error to leave hashCode abstract if equals is implemented, and vice versa, as FreeBuilder has no reasonable way to ensure the consistency of any implementation it might generate.\n\nIf you have a small set of properties you wish to exclude from equals or toString without losing the generated code entirely, you can annotate them `@IgnoredByEquals` and/or `@NotInToString`.\n\n**Warning:**\nIt is rarely a good idea to redefine equality on a value type, as it makes testing very hard.\nFor instance, `assertEquals` in JUnit relies on equality; it will not know to check individual fields, and as a result, tests may be failing to catch bugs that, on the face of it, they looks like they should be.\nIf you are only testing a subset of your fields for equality, consider separating your class in two, as you may have accidentally combined the key and the value of a map into a single object, and you may find your code becomes healthier after the separation.\nAlternatively, creating a custom [Comparator] will make it explicit that you are not using the natural definition of equality.\n\n### Custom conventional method names\n\nIf for any reason your types cannot use the conventional method names (`build`, `buildPartial`, `clear` and `mergeFrom`), you can force FreeBuilder to generate package protected implementations, and even select alternative fallback names if necessary, by declaring an alternative visibility and/or incompatible signature. If the default name is not available, FreeBuilder will prepend an underscore and append \"Impl\" (and, if necessary, a number), e.g. `build` becomes `_buildImpl`.\n\n```java\npublic interface MyType {\n  class Builder extends MyType_Builder {\n    public OtherDataType build() {\n      // This signature is not compatible with the default build method.\n      // FreeBuilder will instead declare a package-scoped _buildImpl.\n      ...\n    }\n    public DataType buildMyType() {\n      return _buildImpl();\n    }\n  }\n}\n```\n\nNote that this will, unfortunately, disable FreeBuilder's [enhanced support for nested builders](#nested-buildable-types) for this type, as it needs to be able to call these methods.\n\n### Custom functional interfaces\n\nFreeBuilder's generated map and mutate methods take [UnaryOperator] or [Consumer] functional interfaces. If you need to use a different functional interface, you can override the generated methods in your Builder and change the parameter type. FreeBuilder will spot the incompatible override and change the code it generates to match:\n\n```java\npublic interface MyType {\n  String property();\n\n  class Builder extends MyType_Builder {\n    @Override public Builder mapProperty(\n        com.google.common.base.Function\u003cInteger, Integer\u003e mapper) {\n      return super.mapProperty(mapper);\n    }\n  }\n}\n```\n\n### Builder construction\n\n\u003cem\u003eEffective Java\u003c/em\u003e recommends passing required parameters in to the Builder\nconstructor. While we follow most of the recommendations therein, we explicitly\ndo not follow this one: while you gain compile-time verification that all\nparameters are set, you lose flexibility in client code, as well as opening\nyourself back up to the exact same subtle usage bugs as traditional constructors\nand factory methods. For the default FreeBuilder case, where all parameters\nare required, this does not scale.\n\nIf you want to follow \u003cem\u003eEffective Java\u003c/em\u003e more faithfully in your own types,\nhowever, just create the appropriate constructor in your builder subclass:\n\n\n```java\n    public Builder(String name, int age) {\n      // Set all initial values in the builder constructor\n      name(name);\n      age(age);\n    }\n```\n\nImplementation note: in javac, we spot these fields being set in the\nconstructor, and do not check again at runtime. \n\n\n### Partials\n\nA \u003cem\u003epartial value\u003c/em\u003e is an implementation of the value type which does not\nconform to the type's state constraints. It may be missing required fields, or\nit may violate a cross-field constraint.\n\n\n```java\nPerson person = new Person.Builder()\n    .name(\"Phil\")\n    .buildPartial();  // build() would throw an IllegalStateException here\nSystem.out.println(person);  // prints: partial Person{name=Phil}\nperson.age();  // throws UnsupportedOperationException\n```\n\nAs partials violate the (legitimate) expectations of your program, they must\n\u003cstrong\u003enot\u003c/strong\u003e be created in production code. (They may also affect the\nperformance of your program, as the JVM cannot make as many optimizations.)\nHowever, when testing a component which does not rely on the full state\nrestrictions of the value type, partials can reduce the fragility of your test\nsuite, allowing you to add new required fields or other constraints to an\nexisting value type without breaking swathes of test code.\n\nTo allow robust tests of modify-rebuild code, Builders created from partials\n(either via the static `Builder.from` method or the optional `toBuilder()`\nmethod) will override `build()` to instead call `buildPartial()`.\n\n```java\nPerson anotherPerson = person.toBuilder().name(\"Bob\").build();\nSystem.out.println(anotherPerson);  // prints: partial Person{name=Bob}\n```\n\nThis \"infectious\" behavior of partials is another reason to confine them to\ntest code.\n\n(Note the `mergeFrom` method does not behave this way; instead, it will throw an\nUnsupportedOperationException if given a partial.)\n\n\n### Jackson\n\nTo create types compatible with the [Jackson JSON serialization\nlibrary][Jackson], use the builder property of [@JsonDeserialize] to point Jackson\nat your Builder class. For instance:\n\n```java\n// This type can be freely converted to and from JSON with Jackson\n@JsonDeserialize(builder = Address.Builder.class)\ninterface Address {\n    String city();\n    String state();\n\n    class Builder extends Address_Builder {}\n}\n```\n\nFreeBuilder will generate appropriate [@JsonProperty] annotations on the\nbuilder. (If you use Java 8 or Guava types, you may need to include the\nrelevant Jackson extension modules, [jackson-datatype-jdk8] and\n[jackson-datatype-guava].)\n\n[Jackson]: http://wiki.fasterxml.com/JacksonHome\n[jackson-datatype-guava]: https://github.com/FasterXML/jackson-datatype-guava\n[jackson-datatype-jdk8]: https://github.com/FasterXML/jackson-datatype-jdk8\n[@JsonProperty]: http://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonProperty.html\n[@JsonDeserialize]: http://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/annotation/JsonDeserialize.html\n\n\n### GWT\n\nTo enable [GWT][] serialization of the generated Value subclass, just add\n`@GwtCompatible(serializable = true)` to your `@FreeBuilder`-annotated type, and\nextend/implement `Serializable`. This will generate a [CustomFieldSerializer][],\nand ensure all necessary types are whitelisted.\n\n[GWT]: http://www.gwtproject.org/\n[CustomFieldSerializer]: http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/rpc/CustomFieldSerializer.html\n\n\nBuild tools and IDEs\n--------------------\n\n### javac\n\nDownload [the latest FreeBuilder JAR] and add it to the classpath (or\nprocessorpath, if you supply one) on the command line. If [Guava] is\navailable, FreeBuilder will use it to generate cleaner, more\ninteroperable implementation code (e.g returning [immutable collections]).\n\n[the latest FreeBuilder JAR]: https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy\u0026g=org.inferred\u0026a=freebuilder\u0026v=RELEASE\n[immutable collections]: https://github.com/google/guava/wiki/ImmutableCollectionsExplained\n\n### Maven\n\nAdd the FreeBuilder artifact as an optional dependency to your Maven POM:\n\n```xml\n\u003cdependencies\u003e\n  \u003cdependency\u003e\n    \u003cgroupId\u003eorg.inferred\u003c/groupId\u003e\n    \u003cartifactId\u003efreebuilder\u003c/artifactId\u003e\n    \u003cversion\u003e[current version]\u003c/version\u003e\n    \u003coptional\u003etrue\u003c/optional\u003e\n  \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nIf [Guava] is available, FreeBuilder will use it to generate cleaner, more\ninteroperable implementation code (e.g returning [immutable collections]).\n\n### Gradle\n\n#### 4.6+\n\nAdd the following lines to your project's build.gradle file:\n\n```\ndependencies {\n  annotationProcessor 'org.inferred:freebuilder:\u003ccurrent version\u003e'\n  compileOnly 'org.inferred:freebuilder:\u003ccurrent version\u003e'\n}\n```\n\nIf [Guava] is available, FreeBuilder will use it to generate cleaner, more\ninteroperable implementation code (e.g returning [immutable collections]).\nYou may also wish to use the [org.inferred.processors plugin] to correctly configure code\ngeneration in your IDE.\n\n#### Pre-4.6\n\nAdd the following lines to your project's build.gradle file:\n\n```\nplugins {\n  id 'org.inferred.processors' version '1.2.10'\n}\n\ndependencies {\n  processor 'org.inferred:freebuilder:\u003ccurrent version\u003e'\n}\n```\n\nThis uses the [org.inferred.processors plugin] to correctly configure code generation in\nyour IDE. Alternatively, you can drop the plugin and replace `processor` with\n[`compileOnly`], or `compile` if you are on Gradle 2.11 or earlier—you will lose IDE\nintegration—or use your own favourite Gradle annotation processor plugin.\n\nIf [Guava] is available, FreeBuilder will use it to generate cleaner, more\ninteroperable implementation code (e.g returning [immutable collections]).\n\n[org.inferred.processors plugin]: https://github.com/palantir/gradle-processors\n[`compileOnly`]: https://blog.gradle.org/introducing-compile-only-dependencies\n\n### Eclipse\n\n_Condensed from [Eclipse Indigo's documentation][]._\n\nDownload [the latest FreeBuilder JAR] and add it to your project. Select it,\nright-click and choose **Build path \u003e Add to Build path**.\n\nIn your projects properties dialog, go to **Java Compiler \u003e Annotation\nProcessing** and ensure **Enable annotation processing** is checked.\nNext, go to **Java Compiler \u003e Annotation Processing \u003e Factory Path**, select\n**Add JARs**, and select the FreeBuilder JAR.\n\n[Eclipse Indigo's documentation]: http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Fguide%2Fjdt_apt_getting_started.htm\n\n### IntelliJ\n\n_Condensed from the [IntelliJ 14.0.3 documentation][] and [Auto Issue #106][]._\n\nDownload [the latest FreeBuilder JAR], add it to your project, right-click it\nand select **Use as Project Library**.\n\nIn your Settings, go to **Build, Execution, Deployment \u003e Compiler \u003e Annotation\nProcessors** and ensure **Enable annotation processing** is selected, and\n**Store generated sources relative to** is set to *Module content root*.\n(If you have specified a processor path, ensure you add the new JAR to it.\nSimilarly, if you choose to specify processors explicitly, add\n`org.inferred.freebuilder.processor.Processor` to the list.)\n\nRun **Build \u003e Rebuild Project**, then right-click the new `generated` folder\n(this may have a different name if you have changed the **Production sources\ndirectory** setting) and select **Mark Directory As \u003e Generated Sources Root**.\n\n\nIf you are using Maven to build your project within IntelliJ, you can alternatively\nconfigure the POM in a way that enables IntelliJ to automatically detect annotation\nprocessors when the POM is reloaded:\n\n```\n\u003cplugin\u003e\n    \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n    \u003cconfiguration\u003e\n        \u003cannotationProcessors\u003e\n            \u003cannotationProcessor\u003eorg.inferred.freebuilder.processor.Processor\u003c/annotationProcessor\u003e\n        \u003c/annotationProcessors\u003e\n        \u003cannotationProcessorPaths\u003e\n            \u003cpath\u003e\n                \u003cgroupId\u003eorg.inferred\u003c/groupId\u003e\n                \u003cartifactId\u003efreebuilder\u003c/artifactId\u003e\n                \u003cversion\u003e2.6.2\u003c/version\u003e\n            \u003c/path\u003e\n        \u003c/annotationProcessorPaths\u003e\n    \u003c/configuration\u003e\n\u003c/plugin\u003e\n```\n\nClick **Reload All Maven Projects** in the Maven tool window to force a reload if you have not configured IntelliJ\nfor automatic reloading. The Annotation processor should appear in **Build, Execution, Deployment \u003e Compiler \u003e Annotation\nProcessors** automatically, with all needed settings applied.\n\nIn case you need to use more than one annotation processor, you'll find an example at https://github.com/inferred/FreeBuilder/issues/435 .\n\n[IntelliJ 14.0.3 documentation]: http://www.jetbrains.com/idea/webhelp/configuring-annotation-processing.html\n[Auto Issue #106]: https://github.com/google/auto/issues/106\n\n\nRelease notes\n-------------\n\n### 2.3—From method testability\n\nFreeBuilder 2.3 now allows partials to be passed to the static `Builder.from`\nmethod. Previously this would have thrown an UnsupportedOperationException\nif any field was unset; now, as with the optional `toBuilder` method, a Builder\nsubclass will be returned that redirects `build` to `buildPartial`. This allows\nunit tests to be written that won't break if new constraints or required fields\nare later added to the datatype. You can restore the old behaviour by overriding\nthe `from` method to delegate to `mergeFrom`.\n\nNote that use of partials outside of tests is considered undefined behaviour\nby FreeBuilder, as documented here and on the `buildPartial` method. Incomplete\nvalues should always be represented by Builder instances, not partials.\n\n### 2.2—Primitive optional types\n\nFreeBuilder 2.2 extends its [optional value API customization](#optional-values)\nto [OptionalInt], [OptionalLong] and [OptionalDouble]. This is, for mutate\nmethods, a non-binary-backwards-compatible change. If you have existing\nproperties that you do not want this to affect, you can force FreeBuilder to\nadhere to your existing API with [custom functional interfaces](#custom-functional-interfaces).\nTo do this, use your IDE to override all mapper methods taking an `OptionalInt`,\n`OptionalLong` or `OptionalDouble` (the implementations can just delegate to\nsuper). One of these will have been generated for each primitive optional\nproperty. Once all such methods are overridden, upgrading to 2.2 should now leave your\nAPIs unaltered.\n\nThis change also alters the default behavior of the Optional-accepting setter method\nto delegate to a new primitive-accepting setter method, to allow constraints to be\nadded through overriding. If you have previously added such a primitive-accepting\nsetter method that delegates to the Optional-accepting setter method, this will of\ncourse now result in a stack overflow at runtime. FreeBuilder will attempt to flag\nthis as a compiler error, but please double-check your builders when upgrading.\n\n[OptionalInt]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalInt.html\n[OptionalLong]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalLong.html\n[OptionalDouble]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalDouble.html\n\n### 2.1—Lists of buildable types\n\nFreeBuilder 2.1 adds more extensive API customization for [lists of buildable types](#lists-of-buildable-types), storing Builder instances internally until build is called, cascading buildPartial automatically, and adding overloads accepting Builder instances.\n\nThis is a behavioural and, for the get and mutate methods, a non-binary-backwards-compatible change. If you have existing properties that you do not want this to affect, see [disabling buildable lists](#disabling-buildable-lists) for instructions on restoring the 2.0 behaviour on a case-by-case basis.\n\n### Upgrading from v1\n\nThere are three API-breaking changes between v1 and v2 of FreeBuilder:\n\n * Mapper methods use primitive, not boxed, functional interfaces for `int`,\n   `long` and `double` properties.\n\n   **This will likely break binary backwards compatibility** for any library\n   using FreeBuilder to generate its builders. We apologise profusely for the\n   hassle this causes. If you simply cannot break your clients, but want to\n   upgrade to v2, you can force FreeBuilder to adhere to your existing API with\n   [custom functional interfaces](#custom-functional-interfaces). To do this,\n   use your IDE to override all mapper methods taking a `UnaryOperator\u003cInteger\u003e`,\n   `UnaryOperator\u003cLong\u003e` or `UnaryOperator\u003cDouble\u003e` (the implementations can\n   just delegate to super). One of these will have been generated for each\n   `int`, `long` and `double` property. Once all such methods are overridden,\n   upgrading to v2 should now leave your APIs unaltered.\n\n * No more support for Java 6/7\n\n   If you are still on Java 6/7, please continue to use the v1 releases of FreeBuilder.\n\n * No longer ships with `javax.annotation.Nullable`\n\n   FreeBuilder treats _any_ annotation named Nullable the same way, so you can either\n   explicitly compile against the old annotation by including\n   [the JSR-305 jar](https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305),\n   or use a more modern alternative, like\n   [org.jetbrains.annotations](https://mvnrepository.com/artifact/org.jetbrains/annotations).\n   (Or use optionals! See [Converting from `@Nullable`](#converting-from-nullable) for\n   advice.)\n\nTroubleshooting\n---------------\n\n\n### Troubleshooting javac\n\nIf you make a mistake in your code (e.g. giving your value type a private\nconstructor), FreeBuilder is designed to output a Builder superclass anyway,\nwith as much of the interface intact as possible, so the only errors you see\nare the ones output by the annotation processor.\n\nUnfortunately, `javac` has a broken design: if _any_ annotation processor\noutputs _any error whatsoever_, *all* generated code is discarded, and all\nreferences to that generated code are flagged as broken references. Since\nyour Builder API is generated, that means every usage of a FreeBuilder\nbuilder becomes an error. This deluge of false errors swamps the actual\nerror you need to find and fix. (See also [the related issue][issue 3].)\n\nIf you find yourself in this situation, search the output of `javac` for the\nstring \"@FreeBuilder type\"; nearly all errors include this in their text.\n\n[issue 3]: https://github.com/inferred/FreeBuilder/issues/3\n\n### Troubleshooting Eclipse\n\nEclipse manages, somehow, to be worse than `javac` here. It will never output\nannotation processor errors unless there is another error of some kind; and,\neven then, only after an incremental, not clean, compile. In practice, most\nmistakes are made while editing the FreeBuilder type, which means the\nincremental compiler will flag the errors. If you find a generated superclass\nappears to be missing after a clean compile, however, try touching the\nrelevant file to trigger the incremental compiler. (Or run javac.)\n\n### Online resouces\n\n  * If you find yourself stuck, needing help, wondering whether a given\n    behaviour is a feature or a bug, or just wanting to discuss FreeBuilder,\n    please join and/or post to [the FreeBuilder mailing list][mailing list].\n  * To see a list of open issues, or add a new one, see [the FreeBuilder\n    issue tracker][issue tracker].\n  * To submit a bug fix, or land a sweet new feature, [read up on how to\n    contribute][contributing].\n\n[mailing list]: https://groups.google.com/forum/#!forum/freebuilder\n[issue tracker]: https://github.com/inferred/freebuilder/issues\n[contributing]: https://github.com/inferred/FreeBuilder/blob/main/CONTRIBUTING.md\n\n\nAlternatives\n------------\n\n### Immutables vs FreeBuilder\n\n\u003cem\u003e\u003cstrong\u003eWhere is Immutables better than FreeBuilder?\u003c/strong\u003e\u003c/em\u003e\n\n[Immutables](https://immutables.github.io/) provides many of the same features as FreeBuilder, plus a whole host more. Some are optional ways to potentially enhance performance, like [derived](https://immutables.github.io/immutable.html#derived-attributes) and [lazy](https://immutables.github.io/immutable.html#lazy-attributes) attributes, [singleton](https://immutables.github.io/immutable.html#singleton-instances) and [interned](https://immutables.github.io/immutable.html#instance-interning) instances, and [hash code precomputation](https://immutables.github.io/immutable.html#precomputed-hashcode). Some are API-changing: [strict builders](https://immutables.github.io/immutable.html#strict-builder) provide a compile-time guarantee that all fields are set (but limit the use of builders as a consequence), while [copy methods](https://immutables.github.io/immutable.html#copy-methods) provide a concise way to clone a value with a single field changed (but require you to reference the generated ImmutableFoo type, not Foo). It provides [advanced binary serialization options](https://immutables.github.io/immutable.html#serialization) and [GSON support](https://immutables.github.io/typeadapters.html). It lets you easily customize the conventional method prefixes. As Immutables is an active project, this list is likely incomplete.\n\n\u003cem\u003e\u003cstrong\u003eWhere is FreeBuilder better than Immutables?\u003c/strong\u003e\u003c/em\u003e\n\nFreeBuilder provides some features that are missing from, or not the default in, Immutables:\n\n * [Partials](#partials).\n * [Builder getter, mapper](#accessor-methods) and [mutation](#collections-and-maps) methods.\n * [Nested builders](#nested-buildable-types).\n * Jackson serialization is [clean and easily customised](#jackson).\n * [GWT support](#gwt)\n * Proxyable types\u003csup\u003e1\u003c/sup\u003e.\n * [Traditional OO customization](#defaults-and-constraints)\u003csup\u003e1\u003c/sup\u003e.\n\nThe first three points are increasingly useful as your interfaces grow in complexity and usage. Partials greatly reduce the fragility of your tests by only setting the values the code being tested actually uses. Your interfaces are liable accumulate more constraints, like new required fields, or cross-field constraints, and while these will be vitally important across the application as a whole, they create a big maintenance burden when they break unit tests for existing code that does not rely on those constraints. Builder getter, mapper and mutation methods and nested builders empower the modify-rebuild pattern, where code changes a small part of an object without affecting the remainder.\n\nThe last two points arise because Immutables is *type-generating*: you write your value type as a prototype, but you always use the generated class. This type is final, meaning you can't proxy it, which unfortunately breaks tools like [Mockito](http://mockito.org/) and its wonderful [smart nulls](http://site.mockito.org/mockito/docs/current/org/mockito/Answers.html#RETURNS_SMART_NULLS). The generated builder is hard to customize as you cannot override methods, explaining why Immutables has so many annotations: for instance, [the `@Value.Check` annotation](https://immutables.github.io/immutable.html#precondition-check-method) is unnecessary in FreeBuilder, as you can simply override the setters or build method to perform field or cross-field validation.\n\n1: But note that you *can* write a Builder subclass in your Foo type, enabling FreeBuilder-style override-based customization, though that is not the default approach recommended in the guide, and you will break all your callers if you change between the two.\n\nImmutables is a very active project, frequently adding new features, and future releases may address some or all of these deficiencies.\n\n### AutoValue vs FreeBuilder\n\n\u003cem\u003e\u003cstrong\u003eWhy is FreeBuilder better than [AutoValue][]?\u003c/strong\u003e\u003c/em\u003e\n\nIt’s not! AutoValue provides an implementing class with a package-visible\nconstructor, so you can easily implement the Factory pattern. If you’re writing\nan immutable type that needs a small number of values to create (Effective Java\nsuggests at most three), and is not likely to require more in future, use the\nFactory pattern.\n\nHow about if you want a builder? [AutoValue.Builder][] lets you explicitly\nspecify a minimal Builder interface that will then be implemented by generated\ncode, while FreeBuilder provides a generated builder API. AutoValue.Builder\nis better if you must have a minimal API\u0026mdash;for instance, in an Android\nproject, where every method is expensive\u0026mdash;or strongly prefer a\nvisible-in-source API at the expense of many useful methods. Otherwise, consider\nusing FreeBuilder to implement the Builder pattern.\n\n\u003cem\u003e\u003cstrong\u003eI used [AutoValue][], but now have more than three properties! How\ndo I migrate to FreeBuilder?\u003c/strong\u003e\u003c/em\u003e\n\n  1. Change your annotation to `@FreeBuilder`.\n  2. Rewrite your factory method(s) to use the builder API.\n  3. Inline your factory method(s) with a refactoring tool (e.g. Eclipse).\n\nYou can always skip step 3 and have both factory and builder methods, if that\nseems cleaner!\n\n\n\u003cem\u003e\u003cstrong\u003eCan I use both [AutoValue][] and FreeBuilder?\u003c/strong\u003e\u003c/em\u003e\n\nNot really. You can certainly use both annotations, but you will end up with\ntwo different implementing classes that never compare equal, even if they have\nthe same values.\n\n[AutoValue]: https://github.com/google/auto/tree/master/value\n[AutoValue.Builder]: https://github.com/google/auto/tree/master/value#builders\n\n\n### Proto vs FreeBuilder\n\n\u003cem\u003e\u003cstrong\u003e[Protocol buffers][] have provided builders for ages. Why should I\nuse FreeBuilder?\u003c/strong\u003e\u003c/em\u003e\n\nProtocol buffers are cross-platform, backwards- and forwards-compatible, and\nhave a very efficient wire format. Unfortunately, they do not support custom\nvalidation logic; nor can you use appropriate Java domain types, such as\n[Instant][] or [Range][]. Generally, it will be clear which one is appropriate\nfor your use-case.\n\n[Protocol buffers]: https://developers.google.com/protocol-buffers/\n[Instant]: http://docs.oracle.com/javase/8/docs/api/java/time/Instant.html\n[Range]: http://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Range.html\n\n\nWait, why \"free\"?\n-----------------\n\n  * Free as in beer: you don't pay the cost of writing or maintaining the builder\n    code.\n  * Free as in flexible: you should always be able to customize the builder where\n    the defaults don't work for you.\n  * Free as in liberty: you can always drop FreeBuilder and walk away with\n    the code it generated for you.\n\nLicense\n-------\n\n    Copyright 2014-7 Google Inc., 2018 Inferred.Org. All rights reserved.\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n        http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","funding_links":[],"categories":["Java","Projects","HarmonyOS","项目"],"sub_categories":["Code Generators","Windows Manager","代码生成器"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finferred%2FFreeBuilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finferred%2FFreeBuilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finferred%2FFreeBuilder/lists"}