声明注解与Java 8引入的类型注解(JSR308)有何区别?
Hey there! Since you're just starting out with Java 8 and already familiar with type annotations (introduced via JSR 308), let's break down how they differ from the more traditional declaration annotations—I'll keep it straightforward with examples so it clicks easily.
Let's start with clear definitions and code examples for both, so you can spot the difference at a glance.
Declaration Annotations
These are the "classic" annotations you've probably already used without realizing it—they attach to the declaration of a program element (like a class, method, field, or parameter). Think of them as labels for the "thing itself", not how the thing is used.
Examples:
// Annotation on a method declaration (tells compiler this overrides a parent method) @Override public String toString() { return super.toString(); } // Annotation on a field declaration (marks this field as outdated) @Deprecated private int legacyField; // Annotation on a class declaration (Spring uses this to mark a controller) @Controller public class UserController { }
Type Annotations
Introduced in Java 8 via JSR 308, these attach to any place a type is used—not just the declaration of the element. They label how a type is being applied in a specific context, which opens the door for better static code analysis (like catching null pointer bugs early).
Examples:
// Annotation on a variable's type (marks this String can't be null) @NonNull String username; // Annotation on a generic parameter (marks all elements in this list are non-null) List<@NonNull String> userNames; // Annotation on a cast type (marks the result of this cast won't be null) String str = (@NonNull String) someObject; // Annotation on a method's return type (marks this method never returns null) public @NonNull String getUsername() { return username; }
Now let's distill the key distinctions between the two:
Where they can be placed
- Declaration annotations: Only on the declaration of elements (class, method, field, etc.). You can't put them inside the "type part" of a statement.
- Type annotations: Anywhere a type is referenced—variable types, generic parameters, casts, return types, array element types, even exception types in
throwsclauses.
What they target
- Declaration annotations: Describe the entire element's properties. For example,
@Deprecatedsays "this field/method/class is no longer recommended to use", regardless of how it's used. - Type annotations: Describe the specific usage of a type. For example,
@NonNull Stringsays "this particular variable can never hold a null value", even if otherStringvariables in the code can be null.
- Declaration annotations: Describe the entire element's properties. For example,
Common use cases
- Declaration annotations: Marking method overrides, deprecating code, configuring frameworks (like Spring's
@Service), suppressing compiler warnings. - Type annotations: Enhancing type safety (null checks, valid value ranges), enabling static code analysis tools to catch bugs before runtime.
- Declaration annotations: Marking method overrides, deprecating code, configuring frameworks (like Spring's
As a Java 8 beginner, you'll likely use declaration annotations daily (like @Override) and type annotations more often when working with static analysis tools or libraries that enforce stricter type rules.
内容的提问来源于stack exchange,提问作者saga




