import groovy.transform.Canonical import groovy.transform.TupleConstructor @Canonical @TupleConstructor class Person { int id String firstName String lastName Date birthdate }
import java.util.Date; import java.util.Map; public class Person { private int id; private String firstName; private String lastName; private Date birthdate; // @TupleConstructor- public Person(Map parameters){ this.id = (int) parameters.get("id"); this.firstName = (String) parameters.get("firstName"); this.lastName = (String) parameters.get("lastName"); this.birthdate = (Date) parameters.get("birthdate"); } public Person(int id, String firstName, String lastName, Date birthdate) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.birthdate =birthdate; } public Person(int id, String firstName, String lastName) { this(id, firstName, lastName, null); } public Person(int id, String firstName) { this(id, firstName, null, null); } public Person(int id) { this(id, null, null, null); } public Person() { this(0, null, null, null); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (id != person.id) return false; if (birthdate != null ? !birthdate.equals(person.birthdate) : person.birthdate != null) return false; if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) return false; if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) return false; return true; } @Override public int hashCode() { int result = id; result = 31 * result + (firstName != null ? firstName.hashCode() : 0); result = 31 * result + (lastName != null ? lastName.hashCode() : 0); result = 31 * result + (birthdate != null ? birthdate.hashCode() : 0); return result; } @Override public String toString() { return "Person{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", birthdate=" + birthdate + '}'; } public int getId() { return this.id; } public void setId(int paramInt) { this.id = paramInt; } public String getFirstName() { return this.firstName; } public void setFirstName(String paramString) { this.firstName = paramString; } public String getLastName() { return this.lastName; } public void setLastName(String paramString) { this.lastName = paramString; } public Date getBirthdate() { return this.birthdate; } public void setBirthdate(Date paramDate) { this.birthdate = paramDate; } }
class Person { String name }
private
(in this case, name
), and all getters and setters are written (well, in this case, only getName()
and setName(String name)
, but the idea is clear).@Bindable
. Although, if you look at how much code it throws, it may not be strange).@Bindable
and her friend @Vetoable
turn getters and setters into real properties, with the ability to hook listeners to them and listen, regarant and prohibit changes.@Category
and @Mixin
add the nature of one class to another class. Well, impurities !@Delegate
adds all the methods that the delegate has, implementing them, naturally, by the delegation, yes? class Event { String name @Delegate Date date }
import java.util.Date; public class Event { private String name; private Date date; public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Date getDate() { return this.date; } public void setDate(Date paramDate) { this.date = paramDate; } public boolean after(Date otherDate) { return date.after(otherDate); } public boolean before(Date otherDate) { return date.before(otherDate); } public long getTime() { return date.getTime(); } public void setTime(long timestamp) { date.setTime(timestamp); } }
@Immutable
makes the class immutable, and specifically:ReadOnlyPropertyException
final
private
and final
equals
, hashcode
and toString
@InheritConstructors
adds all constructors from the @TupleConstructor
, @TupleConstructor
adds a map constructor, in which keys are field names and values ​​are values ​​(see the first example of this @AutoClone
), @AutoClone
and @AutoExternalize
add the corresponding methods, and @Canonical
does the “right Java class” - with a constructor without parameters, constructors that take all parameters (both in a row and mapa), and equals
, hashCode
and toString
. Well, as @Immutable
, only mutable - we also saw it in the first example.@Lazy
will create a lazy-initialized field (on demand), optionally wrapped in soft-reference@Newify
allows you to create objects using the new
method instead of the name of the constructor (as in Ruby), or, conversely, only by the name of the constructor, without new
(as in Python). Here, perhaps, an example would not hurt: @Newify rubyLikeNew() { assert Integer.new(42) == 42 }
@Newify([Tree, Leaf]) buildTree() { Tree(Tree(Leaf(1), Leaf(2)), Leaf(3)) }
Tree
and Leaf
without using new
. Compare with the Java equivalent: public Tree buildTree() { return new Tree(new Tree(new Leaf(1), new Leaf(2)), new Leaf(3)); }
public
. How to make a package
? Through @PackageScope
transformation!@Singleton
over the class, and a lazily-initialized singleton with a double check of locking is ready.@Memoized
2.2 @Memoized
, which remembers the result of the method, and if it is called again, returns the result immediately (and yes, the parameters matter)@NotYetImplemented
- it reverses the results of the JUnit tests: those that should fall, pass, and vice versa. In addition, it reminds def true=false //happy debugging
, this thing is useful for TDD - we throw tests for all methods, including those that are not yet registered, and force tests that should not yet and cannot work to pass with using @NotYetImplemented
. Thus, the fall of these tests will not prevent us from testing the rest.@CompileStatic
, @Field
, and a whole set of annotations for the endowment of suffering for concurency, but this is, all the same, another time (well, or, see point 1 of brazen PR at the end of the post).Source: https://habr.com/ru/post/215343/
All Articles