package com.puppycrawl.tools.checkstyle.checks.modifier;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class InputTypeAnnotations extends MyClass {
// Simple type definitions with type annotations
private @TypeAnnotation String hello = "Hello, World!";
private @TypeAnnotation final String jdk = "JDK8";
@TypeAnnotation private String projectName = "Checkstyle";
// We can use type Annotations with generic type arguments
private Map.@TypeAnnotation Entry entry;
// Type annotations can also be applied to nested types
private List<@TypeAnnotation String> strings;
// Constructors with type annotations
{
new @TypeAnnotation Object();
}
static {
new @TypeAnnotation Object();
}
public void foo1() {
new @TypeAnnotation Object();
}
// Type annotations work with nested (non static) class constructors too
public void foo2() {
InputTypeAnnotations myObject = new InputTypeAnnotations();
myObject.new @TypeAnnotation Nested();
}
// Type casts
public void foo3() {
String myString = (@TypeAnnotation String) new Object();
}
// Type annotations with method arguments
private void foo4(final @TypeAnnotation String parameterName) { }
// Inheritance
class MySerializableClass<T> implements @TypeAnnotation Serializable { }
// Nested type annotations
Map<@TypeAnnotation String, @TypeAnnotation List<@TypeAnnotation String>> documents;
// Apply type annotations to intersection types
public <E extends @TypeAnnotation Comparator<E> & @TypeAnnotation Comparable> void foo5() { }
// Including parameter bounds and wildcard bounds
class Folder<F extends @TypeAnnotation File> { }
Collection<? super @TypeAnnotation File> c;
List<@TypeAnnotation ? extends Comparable<T>> unchangeable;
// Throwing exceptions
void foo6() throws @TypeAnnotation IOException { }
// Type annotations in instanceof statements
public void foo7() {
boolean isNonNull = "string" instanceof @TypeAnnotation String;
}
class Nested { }
class T { }
// Type annotation on method return type
@Override
public @TypeAnnotation String toString() { return ""; }
@Override
@TypeAnnotation public int hashCode() { return 1; }
public @TypeAnnotation int foo8() { return 1; }
public @TypeAnnotation boolean equals(Object obj) { return super.equals(obj); }
// @TypeAnnotation void foo9() { } <-- Compiletime error: void type cannot be annotated with type annotation
@Override
void foo10() {
super.foo10();
}
}
class MyClass {
// It is annotation on method, but not on type!
@MethodAnnotation void foo10() {}
private @MethodAnnotation void foo11() {}
public @TypeAnnotation MyClass() {}
@ConstructorAnnotation public MyClass(String name) {}
}
enum MyEnum {
@TypeAnnotation A;
}
interface IInterfacable {
default @TypeAnnotation String foo() {
return null;
}
}
@Target({
ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.PARAMETER,
ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@interface TypeAnnotation {
}
@interface MethodAnnotation {}
@interface ConstructorAnnotation {}