PROPOSAL: Auto-assignment Parameters
Reinier Zwitserloot
reinier at zwitserloot.com
Wed Mar 25 09:59:53 PDT 2009
There's no reference for auto-POJOs anywhere, but this should allow
you to write up all you need:
1. 'data' is a context sensitive keyword that is legal on classes. The
'data' keyword will add a number of members to the class.
2. For each field, a getter is generated, according to the beanspec
(getFoo() or isFoo()). if the field is not final, a setter is
generated, according to beanspec (setFoo()), and the field is
considered a property of the data class, unless it is transient. If
the field is public, the getter (and, if not final, the setter), is
not generated. For all generated getters/setters, if the getter/setter
is already in the class, or already defined (that is; not abstract) in
any supertype, then the getter/setter is not generated. protected and
visible package protected members from supertypes are also included
both for generating setters/getters and for hashCode/equals/toString/
clone (upcoming).
3. hashCode() and equals(): Existence of the hashCode() or equals()
method in any supertype is not relevant (obviously; all objects have
them!)
3a. If only one of hashCode() or equals() is present, a warning is
generated and neither hashCode() or equals() is auto-generated. The
warning basically explains that overriding one but not the other is a
bug.
3b. If both hashCode() and equals() are present, nothing happens.
3c. If neither is present, a hashCode() and equals() method are
generated. These involve all properties (non-transient visible
fields). equals() is defined by:
3c1: First check if the other object is of the exact same class as
ourselves; if not, false. If null, false.
3c2: For each primitive property, check via == if they are equal. If
any isn't, false.
3c3: For each object property, call its .equals(). If they aren't,
false.
3c4: return true.
for hashCode(), do whatever eclipse does out of the box to auto-
generate hashCode() methods. It basically looks like:
final int PRIME = 31;
int result = 1;
for ( each field ) result = result*31 + field.hashCode();
return result;
Where hashCode() is generated in obvious fashion for all primitives
(xor the upper and lower bits of longs together, convert floats and
doubles to long/intbits and use that, chars/bytes/ints/shorts's
hashCode is their own value, booleans are translated to 11/17. 'null'
becomes 3.
4. *IF* all fields are private, and *IF* all fields are final, *AND*
the class does not contain any explicit constructors, *AND* the class
has a no-args super constructor, then a constructor is generated that
includes all fields, in order of definition, which simply assigns them
to the fields. visible properties from supertypes aren't included.
5. A toString() method is generated, if not already present in the
type, which produces a string like so: "MyClassName [field1=value,
field2=value]", for all properties. (so, non-visible fields from
supertypes and transient fields are skipped).
6 (optional). Each generated member gets a @Generated annotation,
which is a new annotation ( java.lang.annotations.Generated ). These
are @Documented and @Retention.RUNTIME.
Is it viable for coin? I'll write it up if so.
--Reinier Zwitserloot
On Mar 25, 2009, at 14:41, james lowden wrote:
>
> I'd like to see both. Auto-getters/setters/equals/etc. would be
> really, really nice, but it would also be valuable to have a way of
> specifying a variety of different constructors to generate, which
> Mark's proposal would allow for. Example:
>
> public data class Foo {
> private final int x;
> private final int y;
> private final String foo;
>
> public Foo (this.x) {}
>
> public Foo (this.foo, this.y) {}
> }
>
>
> (I eliminated the types from the automagical constructors, as they
> can be inferred by the compiler.)
>
> This would generate all three getters and setters, equals (),
> hashcode (), a general constructor taking in all 3 fields, and two
> additional constructors, one taking in just int x, and one taking in
> both String foo and int y.
>
> Reinier--is there a copy of your original proposal for auto-POJOs
> somewhere?
>
> -JL-
>
>
>> From: Reinier Zwitserloot <reinier at zwitserloot.com>
>> Subject: Re: PROPOSAL: Auto-assignment Parameters
>> To: "Mark Mahieu" <markmahieu at googlemail.com>
>> Cc: coin-dev at openjdk.java.net
>> Date: Tuesday, March 24, 2009, 8:34 PM
>> I like where this is going, but I'd rather see a bigger
>> setup for auto-
>> POJO classes. I proposed this before and in most java
>> circles (outside
>> of coin-dev!), this idea was considered very useful:
>>
>> public data class Foo {
>> private final int x;
>> private final int y;
>> private final String foo;
>> }
>>
>>
>> The above class would auto-generate the getters, a
>> constructor,
>> hashCode, equals, and toString. You can add methods to it
>> if you want,
>> and if you define a method that would usually be
>> auto-generated, it
>> isn't auto-generated. So, if you need to do some extra
>> processing
>> before returning 'foo' via the getter, go right
>> ahead. You can even
>> add this later without breaking your API's
>> compatibility.
>>
>> --Reinier Zwitserloot
>>
>>
>>
>> On Mar 25, 2009, at 02:07, Mark Mahieu wrote:
>>
>>> HTML version + prototype available at
>> http://slm888.com/javac
>>>
>>>
>>>
>>> Auto-assignment Parameters v0.1
>>>
>>>
>>> AUTHOR(S):
>>>
>>> Mark Mahieu
>>>
>>>
>>> OVERVIEW
>>>
>>> FEATURE SUMMARY: Should be suitable as a summary in a
>> language
>>> tutorial.
>>>
>>> An additional form of constructor parameter which
>> provides automatic
>>> assignment of the parameter's value to an instance
>> field. These
>>> parameters
>>> are implicitly declared as final to prevent
>> unintentional
>>> assignments to the
>>> wrong variable in the constructor body.
>>>
>>>
>>> MAJOR ADVANTAGE: What makes the proposal a favorable
>> change?
>>>
>>> Reduces the likelihood of some common coding errors
>> relating to
>>> assignment
>>> of fields in a constructor, including those where:
>>>
>>> * a field is assigned to itself
>>> * the parameter is assigned instead of the field
>>> * the assignment to the field is missing entirely
>>>
>>> These and other errors are often caused by typos or
>> code refactoring.
>>>
>>>
>>> MAJOR BENEFIT: Why is the platform better if the
>> proposal is adopted?
>>>
>>> A programmer's intent is more clearly expressed
>> for the extremely
>>> common
>>> case of assigning a constructor parameter directly to
>> an instance
>>> field with
>>> the same name.
>>>
>>>
>>> MAJOR DISADVANTAGE: There is always a cost.
>>>
>>> As with any sugar which enables a more concise way of
>> expressing an
>>> existing
>>> idiom, programmers may be tempted to use it even when
>> the original
>>> form
>>> would be more appropriate.
>>>
>>>
>>> ALTERNATIVES: Can the benefits and advantages be had
>> some way
>>> without a
>>> language change?
>>>
>>> IDEs and tools such as FindBugs are good at warning
>> about the kind
>>> of errors
>>> mentioned above, however since the code in question is
>> usually still
>>> valid
>>> to the compiler, they are limited in what action they
>> can take by
>>> default.
>>>
>>> A language change can combine the ability to avoid
>> these errors
>>> entirely
>>> with a more expressive idiom, resulting in an
>> increased signal to
>>> noise
>>> ratio for readers of that code.
>>>
>>>
>>>
>>> EXAMPLES
>>>
>>> SIMPLE EXAMPLE: Show the simplest possible program
>> utilizing the new
>>> feature.
>>>
>>> class C {
>>> int i;
>>> C(int this.i) {}
>>> }
>>>
>>>
>>> ADVANCED EXAMPLE: Show advanced usage(s) of the
>> feature.
>>>
>>>
>>> class Proposal {
>>>
>>> private final String name;
>>> private final String author;
>>> private boolean suitableForCoin;
>>> private Integer score;
>>>
>>> public Proposal(String this.name,
>>> String this.author,
>>> boolean this.suitableForCoin,
>>> int this.score) {
>>>
>>> if (name.equals(“Auto-assignment
>> Parameters”)) {
>>> suitableForCoin = true; // final so
>> compile-time error
>>> }
>>> }
>>>
>>> // rest of class ...
>>> }
>>>
>>>
>>>
>>> DETAILS
>>>
>>>
>>> SPECIFICATION: Describe how the proposal affects the
>> grammar, type
>>> system,
>>> and meaning of expressions and statements in the Java
>> Programming
>>> Language
>>> as well as any other known impacts.
>>>
>>> The syntactic grammar is modified to include
>> auto-assignment
>>> parameters for
>>> constructors:
>>>
>>> ConstructorDeclaratorRest:
>>> ConstructorParameters [throws
>> QualifiedIdentifierList]
>>> MethodBody
>>>
>>> ConstructorParameters:
>>> ( [ConstructorParameterDecls] )
>>>
>>> ConstructorParameterDecls:
>>> [final] [Annotations] Type
>>> ConstructorParameterDeclsRest
>>>
>>> ConstructorParameterDeclsRest:
>>> ConstructorParameterId [ ,
>> ConstructorParameterDecls]
>>> ... ConstructorParameterId
>>>
>>> ConstructorParameterId:
>>> VariableDeclaratorId
>>> this . VariableDeclaratorId
>>> super . VariableDeclaratorId
>>>
>>> An auto-assignment parameter is a formal parameter
>> (JLSv3 §8.4.1)
>>> which
>>> specifies an instance field instead of an identifier.
>> Its value is
>>> automatically assigned to the specified field. It may
>> only be used
>>> in a
>>> constructor.
>>>
>>> The automatic assignment takes place after any
>> explicit or implicit
>>> invocation of another constructor, and before any
>> statements in the
>>> body of
>>> the constructor. A constructor which declares n
>> auto-assignment
>>> parameters
>>> will perform n such automatic assignments, in the
>> order that the
>>> parameters
>>> are declared.
>>>
>>> The parameter has the same name (JLSv3 §6.2) as the
>> field to which
>>> it is
>>> assigned; replacing each auto-assignment parameter
>> with a normal
>>> formal
>>> parameter with the same name would yield a constructor
>> with an
>>> identical
>>> signature. As with a normal parameter, the
>> parameter's name is
>>> entered into
>>> the scope of the constructor body (JLSv3 §6.3), and
>> therefore
>>> shadows the
>>> field (JLSv3 §6.3.1) within that scope.
>>>
>>> It is a compile-time error if the field is not
>> accessible from the
>>> constructor in which the parameter appears.
>>>
>>> It is a compile-time error if the declared type of the
>> parameter is
>>> not
>>> assignment compatible (JLSv3 §5.2) with the field to
>> which it is
>>> automatically assigned.
>>>
>>> If an unboxing conversion is required by an automatic
>> assignment, any
>>> NullPointerException thrown as a result (JLSv3
>> §5.1.8) will contain
>>> the name
>>> of the field on which the conversion failed, which may
>> be retrieved by
>>> calling getMessage() on the exception.
>>>
>>> Auto-assignment parameters are implicitly final, and
>> follow the
>>> standard
>>> rules for final variables (JLSv3 §4.12.4).
>> Explicitly declaring an
>>> auto-assignment parameter as final has no effect, and
>> does not cause a
>>> compilation error.
>>>
>>> Auto-assignment parameters follow the standard
>> definite assignment
>>> rules for
>>> formal parameters (JLSv3 §16.3).
>>>
>>> An auto-assignment parameter may be annotated.
>>>
>>> If an auto-assignment parameter is the last parameter
>> in the list, and
>>> refers to a field of array type, it may be a variable
>> arity parameter.
>>>
>>>
>>>
>>> COMPILATION: How would the feature be compiled to
>> class files? Show
>>> how the
>>> simple and advanced examples would be compiled.
>> Compilation can be
>>> expressed
>>> as at least one of a desugaring to existing source
>> constructs and a
>>> translation down to bytecode. If a new bytecode is
>> used or the
>>> semantics of
>>> an existing bytecode are changed, describe those
>> changes, including
>>> how they
>>> impact verification. Also discuss any new class file
>> attributes that
>>> are
>>> introduced. Note that there are many downstream tools
>> that consume
>>> class
>>> files and that they may to be updated to support the
>> proposal!
>>>
>>> Desugaring of the following class:
>>>
>>> class Foo {
>>> int value;
>>> Foo(Integer this.value) {
>>> System.out.println(value);
>>> }
>>> }
>>>
>>> would result in (unboxing desugaring omitted):
>>>
>>> class Foo {
>>> int value;
>>> Foo(final Integer value) {
>>> super();
>>> if (value == null)
>>> throw new
>> NullPointerException("value");
>>> this.value = value;
>>> System.out.println(value);
>>> }
>>> }
>>>
>>> No changes to the classfile format are required.
>> Tools which
>>> consume class
>>> files see the constructor signature as though it had
>> been written
>>> using
>>> normal formal parameters.
>>>
>>>
>>> TESTING: How can the feature be tested?
>>>
>>> An initial set of jtreg tests is included in the
>> prototype.
>>>
>>>
>>> LIBRARY SUPPORT: Are any supporting libraries needed
>> for the feature?
>>>
>>> No
>>>
>>>
>>> REFLECTIVE APIS: Do any of the various and sundry
>> reflection APIs
>>> need to be
>>> updated? This list of reflective APIs includes but is
>> not limited to
>>> core
>>> reflection (java.lang.Class and java.lang.reflect.*),
>>
>>> javax.lang.model.*,
>>> the doclet API, and JPDA.
>>>
>>> com.sun.source.tree.VariableTree would require an
>> additional method
>>> which
>>> returns the auto-assigned field.
>>>
>>>
>>> OTHER CHANGES: Do any other parts of the platform need
>> be updated too?
>>> Possibilities include but are not limited to JNI,
>> serialization, and
>>> output
>>> of the javadoc tool.
>>>
>>> No
>>>
>>>
>>> MIGRATION: Sketch how a code base could be converted,
>> manually or
>>> automatically, to use the new feature.
>>>
>>> Assignment statements in constructors for which all of
>> the following
>>> are
>>> true can be considered suitable for conversion:
>>> * the lhs of the assignment is a non-static field
>>> * the rhs is a parameter with the same name as the
>> field
>>> * there are no other assignments to the parameter
>> anywhere in the
>>> constructor
>>> * there are no assignments to, or other uses of
>> the field before
>>> the
>>> assignment statement in question (including invoked
>> constructors)
>>>
>>> Such statements can be converted by:
>>> 1) replacing the parameter with an auto-assignment
>> parameter
>>> (prefixing
>>> the existing parameter's identifier with
>> 'this.'), and
>>> 2) removing the assignment statement
>>>
>>>
>>>
>>> COMPATIBILITY
>>>
>>> BREAKING CHANGES: Are any previously valid programs
>> now invalid? If
>>> so, list
>>> one.
>>>
>>> No
>>>
>>>
>>> EXISTING PROGRAMS: How do source and class files of
>> earlier platform
>>> versions interact with the feature? Can any new
>> overloadings occur?
>>> Can any
>>> new overriding occur?
>>>
>>> The semantics of existing class files and legal source
>> files are
>>> unchanged
>>> by this feature.
>>>
>>>
>>>
>>> REFERENCES
>>>
>>> EXISTING BUGS: Please include a list of any existing
>> Sun bug ids
>>> related to
>>> this proposal.
>>>
>>>
>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394
>>> (uses a 'setter' method rather than a
>> constructor in its example)
>>>
>>> FindBugs bug patterns -
>> http://findbugs.sourceforge.net/bugDescriptions.html
>>> * Self assignment of field (SA_FIELD_SELF_ASSIGNMENT)
>>> * Self comparison of field with itself
>> (SA_FIELD_SELF_COMPARISON)
>>> * Nonsensical self computation involving a field
>> (e.g., x & x)
>>> (SA_FIELD_SELF_COMPUTATION)
>>> * Self assignment of local variable
>> (SA_LOCAL_SELF_ASSIGNMENT)
>>> * Nonsensical self computation involving a variable
>> (e.g., x & x)
>>> (SA_LOCAL_SELF_COMPUTATION)
>>> * Uninitialized read of field in constructor
>> (UR_UNINIT_READ)
>>> * Unwritten field (UWF_UNWRITTEN_FIELD)
>>> * Dead store to local variable (DLS_DEAD_LOCAL_STORE)
>>> * Dead store of null to local variable
>> (DLS_DEAD_LOCAL_STORE_OF_NULL)
>>>
>>>
>>>
>>> URL FOR PROTOTYPE (optional):
>>>
>>> http://slm888.com/javac
>>>
>>>
>>>
>>> DESIGN ALTERNATIVES:
>>>
>>> The following variations have been explored and are
>> worth mentioning:
>>>
>>> * Allow auto-assignment parameters on all non-abstract
>> methods.
>>> This may be especially useful on the extremely
>> common 'setter'
>>> methods
>>> in 'value object' classes.
>>>
>>> * Remove the requirement for (or even disallow) the
>> type to be
>>> specified on
>>> auto-assignment parameters.
>>> Experimentation with this idea suggests that it may
>> work quite
>>> well for
>>> constructors, further emphasising the difference in
>> intent and
>>> semantics
>>> from those of normal parameters. However, it may not
>> work so well in
>>> combination with auto-assignment parameters on all
>> non-abstract
>>> methods, and
>>> requires a change to the order in which javac compiles
>> classes (can
>>> still
>>> pass jtreg tests).
>>>
>>> * Allow an alternative name to be specified.
>>> This adds additional complexity to support a
>> fractional
>>> percentage of
>>> cases, which could continue to use the existing coding
>> pattern.
>>>
>
>
>
>
More information about the coin-dev
mailing list