1   package com.puppycrawl.tools.checkstyle.checks.modifier.modifierorder;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.io.Serializable;
6   import java.lang.annotation.ElementType;
7   import java.lang.annotation.Target;
8   import java.util.Collection;
9   import java.util.Comparator;
10  import java.util.List;
11  import java.util.Map;
12  
13  public class InputModifierOrderTypeAnnotations extends MyClass {
14  
15      // Simple type definitions with type annotations
16      private @TypeAnnotation String hello = "Hello, World!";
17      private @TypeAnnotation final String jdk = "JDK8";
18      @TypeAnnotation private String projectName = "Checkstyle";
19  
20      // We can use type Annotations with generic type arguments
21      private Map.@TypeAnnotation Entry entry;
22      // Type annotations can also be applied to nested types
23      private List<@TypeAnnotation String> strings;
24  
25      // Constructors with type annotations
26      {
27          new @TypeAnnotation Object();
28      }
29  
30      static {
31          new @TypeAnnotation Object();
32      }
33  
34      public void foo1() {
35          new @TypeAnnotation Object();
36      }
37  
38      // Type annotations work with nested (non static) class constructors too
39      public void foo2() {
40          Object myObject = new Object();
41          //myObject.new @TypeAnnotation Nested();
42      }
43  
44      // Type casts
45      public void foo3() {
46          String myString = (@TypeAnnotation String) new Object();
47  
48      }
49  
50      // Type annotations with method arguments
51      private void foo4(final @TypeAnnotation String parameterName) { }
52  
53      // Inheritance
54      class MySerializableClass<T> implements @TypeAnnotation Serializable {  }
55  
56      // Nested type annotations
57      Map<@TypeAnnotation String, @TypeAnnotation List<@TypeAnnotation String>> documents;
58  
59      // Apply type annotations to intersection types
60      public <E extends @TypeAnnotation Comparator<E> & @TypeAnnotation Comparable> void foo5() {  }
61  
62      // Including parameter bounds and wildcard bounds
63      class Folder<F extends @TypeAnnotation File> { }
64      Collection<? super @TypeAnnotation File> c;
65      List<@TypeAnnotation ? extends Comparable<T>> unchangeable;
66  
67      // Throwing exceptions
68      void foo6() throws @TypeAnnotation IOException { }
69  
70      // Type annotations in instanceof statements
71      public void foo7() {
72          boolean isNonNull = "string" instanceof @TypeAnnotation String;
73  
74      }
75  
76      class Nested { }
77  
78      class T { }
79  
80      // Type annotation on method return type
81      @Override
82      public @TypeAnnotation String toString() { return ""; }
83  
84      @Override
85      @TypeAnnotation public int hashCode() { return 1; }
86  
87      public @TypeAnnotation int foo8() { return 1; }
88  
89      public @TypeAnnotation boolean equals(Object obj) { return super.equals(obj); }
90  
91  //    @TypeAnnotation void foo9() { } <-- Compiletime error:
92                                          // void type cannot be annotated with type annotation
93  
94      @Override
95      void foo10() {
96          super.foo10();
97      }
98  }
99  
100 class MyClass {
101 
102     // It is annotation on method, but not on type!
103     @MethodAnnotation void foo10() {}
104     private @MethodAnnotation void foo11() {}
105 
106     public @TypeAnnotation MyClass() {}
107     @ConstructorAnnotation public MyClass(String name) {}
108 }
109 
110 enum MyEnum {
111     @TypeAnnotation A;
112 }
113 
114 interface IInterfacable {
115     default @TypeAnnotation String foo() {
116         return null;
117     }
118 }
119 
120 @Target({
121     ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.PARAMETER,
122     ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
123 @interface TypeAnnotation {
124 }
125 
126 @interface MethodAnnotation {}
127 
128 @interface ConstructorAnnotation {}