# Classes and Members

At a first glance an Xtend file pretty much looks like a Java file. It starts with a package declaration followed by an import section and class definitions. The classes in fact are directly translated to Java classes in the corresponding Java package. A class can have constructors, fields, methods and annotations.

Here is an examplary Xtend file:

package com.acme
import java.util.List
class MyClass {
String name
new(String name) {
this.name = name
}
def String first(List<String> elements) {
elements.get(0)
}
}

## Package Declaration

Package declarations look like in Java. There are two small differences:

- An identifier can be escaped with a ^ character in case it conflicts with a keyword.
- The terminating semicolon is optional.

package com.acme

## Imports

The ordinary imports of type names are equivalent to the imports known from Java. Again one can escape any names conflicting with keywords using a ^. In contrast to Java, the terminating semicolon is optional. Xtend also features static imports but allows only a wildcard * at the end, i.e. you cannot import single members using a static import. Non-static wildcard imports are deprecated for the benefit of better usability and well defined dependencies.

As in Java all classes from the java.lang package are implicitly imported.

import java.math.BigDecimal
import static java.util.Collections.*

Static methods can also be imported as extensions. See the section on extension methods for details.

## Class Declaration

The class declaration reuses a lot of Java's syntax but still is a bit different in some aspects: All Xtend types are public by default since that's the common case. Java's "package private" default visibility is declared by the more explicit keyword package in Xtend. In contrast to Java, Xtend supports multiple public top level class declarations per file. Each Xtend class is compiled to a separate top-level Java class.

Abstract classes are defined using the abstract modifier as in Java. See also section abstractMethods on abstract methods.

Xtend's approach to inheritance is conceptual the same as in Java. Single inheritance of classes as well as implementing multiple interfaces is supported. Xtend classes can extend other Xtend classes, and even Java classes can inherit from Xtend classes. If no super type is specified, Object is used.

The most simple class looks like this:

class MyClass {
}

A more advanced generic class declaration in Xtend:

class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess,
Cloneable, java.io.Serializable {
...
}

## Constructors

An Xtend class can define any number of constructors. Unlike Java you do not have to repeat the name of the class over and over again, but use the keyword new to declare a constructor. Constructors can also delegate to other constructors using this(args...) in their first line.

class MyClass extends AnotherClass {
new(String s) {
super(s)
}
new() {
this("default")
}
}

The same rules with regard to inheritance apply as in Java, i.e. if the super class does not define a no-argument constructor, you have to explicitly call one using super(args...) as the first expression in the body of the constructor.

The default visibility of constructors is public but you can also specify an explicit visiblity public, protected, package or private.

## Fields

A field can have an initializer. Final fields are declared using val, while var introduces a non-final field and can be omitted. Yet, if an initializer expression is present, the type of a field can be inferred if val or var was used to introduce the field. The keyword final is synonym to val. Fields marked as static will be compiled to static Java fields.

class MyClass {
int count = 1
static boolean debug = false
var name = 'Foo' // type String is inferred
val UNIVERSAL_ANSWER = 42 // final field with inferred type int
...
}

The default visibility for fields is private. You can also declare it explicitly as being public, protected, package or private.

A specialty of Xtend are fields that provide extension methods which are covered in their own section.

## Methods

Xtend methods are declared within a class and are translated to a corresponding Java method with exactly the same signature. The only exceptions are dispatch methods, which are explained later.

def String first(List<String> elements) {
elements.get(0)
}

Method declarations start with the keyword def. The default visibility of a plain method is public. You can explicitly declare it as being public, protected, package or private.

Xtend supports the static modifier for methods:

def static createInstance() {
new MyClass('foo')
}

As in Java, vararg parameters are allowed:

def printAll(String... strings) {
strings.forEach[ s | println(s) ]
}

It is possible to infer the return type of a method from its body. Recursive methods and abstract methods have to declare an explicit return type.

### Abstract Methods

An abstract method in Xtend does not define a body and must be declared within an abstract class or an interface. Also specifying the return type is mandatory since it cannot be inferred.

abstract class MyAbstractClass() {
def String abstractMethod() // no body
}

### Overriding Methods

Methods can override other methods from the super class or implement interface methods using the keyword override. If a method overrides a method from a super type, the override keyword is mandatory and replaces the keyword def. The override semantics are the same as in Java, e.g. it is impossible to override final methods or invisible methods. Overriding methods inherit their return type from the super declaration.

Example:

override String second(List<String> elements) {
elements.get(1)
}

### Declared Exceptions

Xtend does not force you to catch or declare checked exceptions. Nevertheless, you can still declare the exceptions thrown in a method's body using the throws clause as in Java.

If you do not declare checked exceptions in your method but they are possibly thrown in your code, the compiler will throw the checked exception silently (using the sneaky-throw technique introduced by Lombok).

/*
* throws an Exception
*/
def void throwException() throws Exception {
throw new Exception
}
/*
* throws an Exception without declaring it
*/
def void sneakyThrowException() {
throw new Exception
}

Optional validation of checked exception is supported, too, and can be configured on the respective Eclipse preference page for the Xtend Errors and Warnings.

### Inferred Return Types

If the return type of a method can be inferred from its body it does not have to be declared.

That is the method

def String second(List<String> elements) {
elements.get(1)
}

could be declared like this:

def second(List<String> elements) {
elements.get(1)
}

The return type is mandatory for abstract method declarations as well as for recursive implementations.

### Generic Methods

You can specify type parameters on methods. A parameterized variant of the method from the previous section, could look like this:

def <T> second(List<T> elements) {
elements.get(1)
}

Type parameter bounds and constraints are supported and share the same syntax and semantics as defined in the the Java Language Specification

### Dispatch Methods

Generally, method resolution and binding is done statically at compile time as in Java. Method calls are bound based on the static types of arguments. Sometimes this is not what you want. Especially in the context of extension methods you would like to have polymorphic behavior.

A dispatch method is declared using the keyword dispatch.

def dispatch printType(Number x) {
"it's a number"
}
def dispatch printType(Integer x) {
"it's an int"
}

For a set of visible dispatch methods in the current type hierarchy with the same name and the same number of arguments, the compiler infers a synthetic dispatcher method. This dispatcher uses the common super type of all declared arguments. The method name of the actual dispatch cases is prepended with an underscore and the visibility of these methods is reduced to protected if they have been defined as public methods. Client code always binds to the synthesized dispatcher method.

For the two dispatch methods in the example above the following Java code would be generated:

protected String _printType(final Number x) {
return "it\'s a number";
}
protected String _printType(final Integer x) {
return "it\'s an int";
}
public String printType(final Number x) {
if (x instanceof Integer) {
return _printType((Integer)x);
} else if (x != null) {
return _printType(x);
} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(x).toString());
}
}

Note that the instanceof cascade is ordered such that more specific types are handled first.

The default visibility of the dispatch cases is protected. If all dispatch methods explicitly declare the same visibility, this will be the visibility of the inferred dispatcher, too. Otherwise it is public. The comparison of the parameter types is performed from left to right. That is in the following example, the second method declaration is considered more specific since its first parameter type is the most specific:

def dispatch printTypes(Number x, Integer y) {
"it's some number and an int"
}
def dispatch printTypes(Integer x, Number y) {
"it's an int and a number"
}

generates the following Java code :

public String printTypes(final Number x, final Number y) {
if (x instanceof Integer
&& y != null) {
return _printTypes((Integer)x, y);
} else if (x != null
&& y instanceof Integer) {
return _printTypes(x, (Integer)y);
} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(x, y).toString());
}
}

The code is compiled in a way that a null reference is never a match. null values can be handled by dispatch cases that use the parameter type Void.

def dispatch printType(Number x) {
"it's some number"
}
def dispatch printType(Integer x) {
"it's an int"
}
def dispatch printType(Void x) {
"it's null"
}

This compiles to the following Java code:

public String printType(final Number x) {
if (x instanceof Integer) {
return _printType((Integer)x);
} else if (x != null) {
return _printType(x);
} else if (x == null) {
return _printType((Void)null);
} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(x).toString());
}
}

#### Dispatch Methods and Inheritance

All visible Java methods from all super types that are conformant to the compiled representation of a dispatch method are also included in the dispatcher. Conforming means they have the expected number of arguments and have the same compiled name with the prepended underscore.

For example, consider the following Java class :

public abstract class AbstractLabelProvider {
protected String _label(Object o) {
// some generic implementation
}
}

and the following Xtend class which extends the Java class :

class MyLabelProvider extends AbstractLabelProvider {
def dispatch label(Entity it) {
name
}
def dispatch label(Method it) {
name+"("+params.join(",")+"):"+type
}
def dispatch label(Field it) {
name+type
}
}

The resulting dispatch method in the generated Java class MyLabelProvider would then look like this:

public String label(final Object it) {
if (it instanceof Entity) {
return _label((Entity)it);
} else if (it instanceof Field) {
return _label((Field)it);
} else if (it instanceof Method) {
return _label((Method)it);
} else if (it != null) {
return super._label(it);
} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(it).toString());
}
}

#### Static Dispatch Methods

Also static dispatch methods are supported. A mixture of static and non-static dispatch methods is prohibited.

## Annotations

Annotations are available on classes, fields, methods and parameters. They are prefixed with the @ character and accept a number of key-value pairs or a single default value for the annotation property named value. Annotation values that expect arrays can handle single values, too. Value arrays are enclosed in array literals #['first', 'second']. The semantics for annotations are exactly like defined in the Java Language Specification. Here is an example:

@TypeAnnotation("some value")
class MyClass {
@FieldAnnotation(value = @NestedAnnotation(true))
static val CONSTANT = 'a compile-time constant'
@MethodAnnotation(constant = CONSTANT)
def String myMethod(@ParameterAnnotation String param) {
//...
}
}

In addition Active Annotations allow users to participate in compilation of Xtend code to Java source code.

Please note that it is currently not possible to use nested annotation values in lists. The following notation is not yet supported but will be implemented in a future release: @Anno( values = #[ @Anno(..) ].

## Extension Methods

Extension methods allow to add new methods to existing types without modifying them. This feature is actually where Xtend got its name from. They are based on a simple syntactic trick: Instead of passing the first argument of an extension method inside the parentheses of a method invocation, the method can be called with the first argument as its receiver - it can be called as if the method was one of the argument type's members.

"hello".toFirstUpper() // calls StringExtensions.toFirstUpper("hello")

Method calls in extension syntax often result in more readable code, as they are chained rather than nested. Another benefit of extensions is that you can add methods which are specific to a certain context or layer of your application.

For instance, you might not want to put UI-specific methods and dependencies into your domain model classes. Therefore this functionality is often defined in static methods or methods in utility classes or service layers. That works, but the code is less readable and less object-oriented if you call methods like this. In Java you often see code like this:

persistenceManager.save(myObject);

Without tying your entities to the persistenceManager, extension methods allow you to write

myObject.save

There are different ways to make methods available as extensions, which are described in the following.

### Extensions from the Library

The Xtend library puts a lot of very useful extension methods on existing types from the Java SDK without any further ado.

"hello".toFirstUpper // calls StringExtensions.toFirstUpper(String)
listOfStrings.map[ toUpperCase ] // calls ListExtensions.<T, R>map(List<T> list, Function<? super T, ? extends R> mapFunction)

Have a look at the JavaDoc to learn about the available functionality:

- ObjectExtensions (src)
- IterableExtensions (src)
- MapExtensions (src)
- ListExtensions (src)
- CollectionExtensions (src)
- BooleanExtensions (src)
- IntegerExtensions (src)
- FunctionExtensions (src)

### Local Extension Methods

All visible non-static methods of the current class and its super types are automatically available as extensions. For example

class MyClass {
def doSomething(Object obj) {
// do something with obj
}
def extensionCall(Object obj) {
obj.doSomething() // calls this.doSomething(obj)
}
}

Local static methods have to be made available through an import like any other static method.

### Extension Imports

In Java, you would usually write a helper class with static methods to decorate an existing class with additional behavior. In order to integrate such static helper classes, Xtend allows to put the keyword extension after the static keyword of a static import thus making all imported static functions available as extensions methods.

The following import declaration

import static extension java.util.Collections.*

allows to use its methods like this:

new MyClass().singletonList()
// calls Collections.singletonList(new MyClass())

### Extension Provider

By adding the extension keyword to a field, a local variable or a parameter declaration, its instance methods become extension methods.

Imagine you want to have some layer specific functionality on a class Person. Let us say you are in a servlet-like class and want to persist a Person using some persistence mechanism. Let us assume Person implements a common interface Entity. You could have the following interface

interface EntityPersistence {
public save(Entity e);
public update(Entity e);
public delete(Entity e);
}

And if you have obtained an instance of that type (through a factory or dependency injection or what ever) like this:

class MyServlet {
extension EntityPersistence ep = Factory.get(EntityPersistence)
...
}

You are able to save, update and delete any entity like this:

val Person person = ...
person.save // calls ep.save(person)
person.name = 'Horst'
person.update // calls ep.update(person)
person.delete // calls ep.delete(person)

Using the extension modifier on values has a significant advantage over static extension imports: Your code is not bound to the actual implementation of the extension method. You can simply exchange the component that provides the referenced extension with another implementation from outside, by providing a different instance.

## Interface Declaration

An interface declaration is very similar to the one in Java. An interface can declare fields, which are by default final static therefore must have an initial value. And of course methods can be declared. They are public by default. Interfaces can extend any number of other interfaces and can declare type parameters.

Here's an example:

interface MyInterface<T> extends OtherInterface {
val CONSTANT = 42
def T doStuff(String ... varArg) throws SomeException
}

## Annotation Type Declaration

Annotation types can also be declared. The are introduced by the keyword annotation and declare their values with a concise syntax:

annotation MyAnnotation {
String[] value
boolean isTricky = false
int[] lotteryNumbers = #[ 42, 137 ]
}

## Enum Type Declaration

Enumeration types are declared like this:

enum MyColor {
GREEN,
BLUE,
RED
}