In this documentation page, concept of synthetic methods for the SARL compiler is introduced. The documentation summarizes what a SARL synthetic method is, how one can be created and identified, and the implications of SARL synthetic methods on SARL development.
Any constructs introduced by the SARL compiler that do not have a corresponding construct in the source code must be marked as synthetic, except for default constructors and the class initialization method. For short, a synthetic function is a SARL construct introduced by the compiler.
The SARL compiler creates synthetic methods on nested classes when their attributes specified with the private modifier are accessed by the enclosing class.
In the following code, the privateField
field is accessed from the fct
function. The SARL compiler generates a synthetic
function for enabling this access.
class EnclosingClass {
static class InnerClass {
var privateField : int
}
def fct(param : InnerClass) {
System.out.println(param.privateField)
}
}
In SARL programming language, the term default constructor can refer to a constructor that is automatically generated by the compiler in the absence of any programmer-defined constructors.
When the current type has not a super-type, the compiler generates a default constructor without formal parameter.
For example, the MyType
class is defined without explicit constructor. An instance of this type may be created by
invoking the implicit/generated default constructor, as illustrated in the fct
function.
class MyType {
}
class CallingType {
def fct {
new MyType
}
}
When the current type has a super-type, the compiler generates a default constructor in the current type for each visible constructor in the super-type. In this case, the generated constructors have the same erasure, i.e. parameters as the super-type’s constructors.
class MySuperType {
new (param1 : int, param2 : String = null) {
}
new (param3 : String) {
}
}
class SubType extends MySuperType {
}
class CallingType {
def fct {
// Call the firstsynthetic constructor
new SubType(14)
new SubType(14, "")
// Call the second synthetic constructor
new SubType("")
}
}
Equality is being used in many programming-language constructs and data types. It is used to test if an element already exists in a set, or to access to a value through a key. It is used in switch statements to dispatch the control flow to the correct branch, and during the unification process in logic programming.
In SARL programming language, objects and data structures are accessed through references. There becomes a need to test for two different types of equality:
A
and B
reference the same object. Interactions with the object through A
are indistinguishable from the same interactions through B
, and in particular changes to the object through A
are reflected through B
.The first type of equality is supported by the ===
equality test, and the !==
innequality test.
The second type of equality is supported by the ==
equality test, and the !=
innequality test.
Because the SARL code is translated to Java code by the SARL compiler, the ==
operator is mapped to the Java equals(Object)
function. The !=
operator is mapped to the Java code !equals(Object)
.
The standard implementation of the ==
operator is usually based on the equality tests on the type’s fields.
In order to help the SARL developer, he does not need to provide explicitly an implementation of the equals
function.
Indeed, the SARL compiler generates a synthetic equals
function when fields of the following types are declared:
int
, float
, etc.;String
, UUID
, etc.For example, consider the following SARL code:
class MyType {
var field1 : int
var field2 : float
var field3 : String
}
The SARL compiler generates the following equals
function in the Java code:
public boolean equals(Object obj) {
if (obj instanceof MyType) {
MyType other = (MyType) obj;
if (this.field1 != other.field1) {
return false;
}
if (this.field2 != other.field2) {
return false;
}
if (!Objects.equals(this.field3, other.field3)) {
return false;
}
return true;
}
return false;
}
Every class implicitly or explicitly provides a hashCode() method in SARL. It digests the datastored in an instance of the
type into a single hash value (a signed integer). This hash is used by other code when storing or manipulating the
instance, i.e. the values are intended to be evenly distributed for varied inputs for use in clustering.
This property is important to the performance of hash tables and other data structures that store objects in groups (“buckets”)
based on their computed hash values. Technically, in SARL (inherited from the Java programming language), hashCode
by
default is a internal object reference (pointer) provided by the JVM.
The general contract for overridden implementations of the hashCode
method is that they behave in a way consistent
with the same object’s equals
method: that a given object must consistently report the same hash value (unless it is
changed so that the new version is no longer considered “equal” to the old), and that two objects which equals
says
are equal must report the same hash value. There’s no requirement that hash values be consistent between different SARL
implementations, or even between different execution runs of the same program, and while two unequal objects having
different hashes is very desirable, this is not mandatory (that is, the hash function implemented doesn’t need to be a
perfect hash).
In order to help the SARL developer, the SARL compielr generates automatically the hashCode
fonction when it is not explicitly
defined by the developer, and fields of the following types are declared:
int
, float
, etc.;String
, UUID
, etc.Serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and reconstructed later in the same or another computer environment. When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object. For many complex objects, such as those that make extensive use of references, this process is not straightforward. Serialization of object-oriented objects does not include any of their associated methods with which they were previously linked.
This process of serializing an object is also called marshalling an object. The opposite operation, extracting a data structure from a series of bytes, is deserialization, which is also called unmarshalling.
In order to have a consistent generated Java code, the SARL compiler generates the private field serialVersionUUID
when
the generated Java type is an implementation of the Serializable
interface.
This interface is used in Java programs for identifying the objects that could be subject of serialization and deserialization.
The Java specification recommends to create a private static field, named serialVersionUUID
for identifying the implementation
of the object, and ensuring that the desrialized object is really of the same type of the serialized object.
Copyright © 2014-2024 SARL.io, the Original Authors and Main Authors.
Documentation text and medias are licensed under the Creative Common CC-BY-SA-4.0; you may not use this file except in compliance with CC-BY-SA-4.0. You may obtain a copy of CC-BY-4.0.
Examples of SARL code are licensed under the Apache License, Version 2.0; you may not use this file except in compliance with the Apache License. You may obtain a copy of the Apache License.
You are free to reproduce the content of this page on copyleft websites such as Wikipedia.
Generated with the translator docs.generator 0.14.0.