Skip to content

Commit c0b5bfc

Browse files
committed
Rewrote annotations section of tour
1 parent 1a5aabb commit c0b5bfc

File tree

1 file changed

+37
-57
lines changed

1 file changed

+37
-57
lines changed

tutorials/tour/_posts/2017-02-13-annotations.md

Lines changed: 37 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -11,77 +11,57 @@ next-page: default-parameter-values
1111
previous-page: automatic-closures
1212
---
1313

14-
Annotations associate meta-information with definitions.
14+
Annotations associate meta-information with definitions. For example, the annotation `@deprecated` before a method causes the compiler to print a warning if the method is used.
15+
```tut:fail
16+
object DepricationDemo extends App {
17+
@deprecated
18+
def hello = "hola"
1519
16-
A simple annotation clause has the form `@C` or `@C(a1, .., an)`. Here, `C` is a constructor of a class `C`, which must conform to the class `scala.Annotation`. All given constructor arguments `a1, .., an` must be constant expressions (i.e., expressions on numeral literals, strings, class literals, Java enumerations and one-dimensional arrays of them).
20+
hello
21+
}
22+
```
23+
This will compile but the compiler will print a warning: "there was one deprecation warning".
1724

1825
An annotation clause applies to the first definition or declaration following it. More than one annotation clause may precede a definition and declaration. The order in which these clauses are given does not matter.
1926

20-
The meaning of annotation clauses is _implementation-dependent_. On the Java platform, the following Scala annotations have a standard meaning.
21-
22-
| Scala | Java |
23-
| ------ | ------ |
24-
| [`scala.SerialVersionUID`](https://www.scala-lang.org/api/current/scala/SerialVersionUID.html) | [`serialVersionUID`](http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html#navbar_bottom) (field) |
25-
| [`scala.deprecated`](https://www.scala-lang.org/api/current/scala/deprecated.html) | [`java.lang.Deprecated`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Deprecated.html) |
26-
| [`scala.inline`](https://www.scala-lang.org/api/current/scala/inline.html) (since 2.6.0) | no equivalent |
27-
| [`scala.native`](https://www.scala-lang.org/api/current/scala/native.html) (since 2.6.0) | [`native`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) |
28-
| [`scala.remote`](https://www.scala-lang.org/api/current/scala/remote.html) | [`java.rmi.Remote`](http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/Remote.html) |
29-
| [`scala.throws`](https://www.scala-lang.org/api/current/scala/throws.html) | [`throws`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) |
30-
| [`scala.transient`](https://www.scala-lang.org/api/current/scala/transient.html) | [`transient`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) |
31-
| [`scala.unchecked`](https://www.scala-lang.org/api/current/scala/unchecked.html) (since 2.4.0) | no equivalent |
32-
| [`scala.volatile`](https://www.scala-lang.org/api/current/scala/volatile.html) | [`volatile`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) |
33-
| [`scala.beans.BeanProperty`](https://www.scala-lang.org/api/current/scala/beans/BeanProperty.html) | [`Design pattern`](http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html) |
34-
35-
In the following example we add the `throws` annotation to the definition of the method `read` in order to catch the thrown exception in the Java main program.
36-
37-
> A Java compiler checks that a program contains handlers for [checked exceptions](http://docs.oracle.com/javase/specs/jls/se5.0/html/exceptions.html) by analyzing which checked exceptions can result from execution of a method or constructor. For each checked exception which is a possible result, the **throws** clause for the method or constructor _must_ mention the class of that exception or one of the superclasses of the class of that exception.
38-
> Since Scala has no checked exceptions, Scala methods _must_ be annotated with one or more `throws` annotations such that Java code can catch exceptions thrown by a Scala method.
39-
40-
```
41-
package examples
42-
import java.io._
43-
class Reader(fname: String) {
44-
private val in = new BufferedReader(new FileReader(fname))
45-
@throws(classOf[IOException])
46-
def read() = in.read()
47-
}
48-
```
4927

50-
The following Java program prints out the contents of the file whose name is passed as the first argument to the `main` method.
28+
## Annotations that ensure correctness of encodings
29+
Certain annotations will actually cause compilation to fail if a condition(s) is not met. For example, the annotation `@tailrec` ensures that a method is [tail-recursive](https://en.wikipedia.org/wiki/Tail_call). Tail-recursion can keep memory requirements constant. Here's how it's used in a method which calculates the factorial:
30+
```tut
31+
import scala.annotation.tailrec
32+
33+
def factorial(x: Int): Int = {
5134
35+
@tailrec
36+
def factorialHelper(x: Int, accumulator: Int): Int = {
37+
if (x == 1) accumulator else factorialHelper(x - 1, accumulator * x)
38+
}
39+
factorialHelper(x, 1)
40+
}
5241
```
53-
package test;
54-
import examples.Reader; // Scala class !!
55-
public class AnnotaTest {
56-
public static void main(String[] args) {
57-
try {
58-
Reader in = new Reader(args[0]);
59-
int c;
60-
while ((c = in.read()) != -1) {
61-
System.out.print((char) c);
62-
}
63-
} catch (java.io.IOException e) {
64-
System.out.println(e.getMessage());
65-
}
66-
}
42+
The `factorialHelper` method has the `@tailrec` which ensures the method is indeed tail-recursive. If we were to change the implementation of `factorialHelper` to the following, it would fail:
43+
```tut:fail
44+
import scala.annotation.tailrec
45+
46+
def factorial(x: Int): Int = {
47+
@tailrec
48+
def factorialHelper(x: Int): Int = {
49+
if (x == 1) 1 else x * factorialHelper(x - 1)
50+
}
51+
factorialHelper(x)
6752
}
6853
```
54+
We would get the message "Recursive call not in tail position".
6955

70-
Commenting out the `throws` annotation in the class Reader produces the following error message when compiling the Java main program:
7156

72-
```
73-
Main.java:11: exception java.io.IOException is never thrown in body of
74-
corresponding try statement
75-
} catch (java.io.IOException e) {
76-
^
77-
1 error
78-
```
57+
## Annotations affecting code generation
58+
Some annotations like `@inline` affect the generated code (i.e. your jar file might have different bytes than if you hadn't used the annotation). Inlining means inserting the code in a method's body at the call site. The resulting bytecode is longer, but hopefully runs faster. Using the annotation `@inline` does not ensure that a method will be inlined, but it will cause the compiler to do it if and only if some heuristics about the size of the generated code are met.
7959

8060
### Java Annotations ###
61+
When writing Scala code which interoperates with Java, there are a few differences in annotation syntax to note.
62+
**Note:** Make sure you use the `-target:jvm-1.8` option with Java annotations.
8163

82-
**Note:** Make sure you use the `-target:jvm-1.5` option with Java annotations.
83-
84-
Java 1.5 introduced user-defined metadata in the form of [annotations](http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html). A key feature of annotations is that they rely on specifying name-value pairs to initialize their elements. For instance, if we need an annotation to track the source of some class we might define it as
64+
Java has user-defined metadata in the form of [annotations](https://docs.oracle.com/javase/tutorial/java/annotations/). A key feature of annotations is that they rely on specifying name-value pairs to initialize their elements. For instance, if we need an annotation to track the source of some class we might define it as
8565

8666
```
8767
@interface Source {

0 commit comments

Comments
 (0)