58 * @param modifiers The modifier flags for the parameter. 59 * @param executable The executable which defines this parameter. 60 * @param index The index of the parameter. 61 */ 62 Parameter(String name, 63 int modifiers, 64 Executable executable, 65 int index) { 66 this.name = name; 67 this.modifiers = modifiers; 68 this.executable = executable; 69 this.index = index; 70 } 71 72 /** 73 * Compares based on the executable and the index. 74 * 75 * @param obj The object to compare. 76 * @return Whether or not this is equal to the argument. 77 */ 78 public boolean equals(Object obj) { 79 if(obj instanceof Parameter) { 80 Parameter other = (Parameter)obj; 81 return (other.executable.equals(executable) && 82 other.index == index); 83 } 84 return false; 85 } 86 87 /** 88 * Returns a hash code based on the executable's hash code and the 89 * index. 90 * 91 * @return A hash code based on the executable's hash code. 92 */ 93 public int hashCode() { 94 return executable.hashCode() ^ index; 95 } 96 97 /** 98 * Returns true if the parameter has a name according to the class 99 * file; returns false otherwise. Whether a parameter has a name 100 * is determined by the {@literal MethodParameters} attribute of 101 * the method which declares the parameter. 102 * 103 * @return true if and only if the parameter has a name according 104 * to the class file. 105 */ 106 public boolean isNamePresent() { 107 return executable.hasRealParameterData() && name != null; 108 } 109 110 /** 111 * Returns a string describing this parameter. The format is the 112 * modifiers for the parameter, if any, in canonical order as 113 * recommended by <cite>The Java™ Language 114 * Specification</cite>, followed by the fully- qualified type of 115 * the parameter (excluding the last [] if the parameter is 116 * variable arity), followed by "..." if the parameter is variable 117 * arity, followed by a space, followed by the name of the 118 * parameter. 119 * 120 * @return A string representation of the parameter and associated 121 * information. 122 */ 123 public String toString() { 124 final StringBuilder sb = new StringBuilder(); 125 final Type type = getParameterizedType(); 126 final String typename = type.getTypeName(); 127 128 sb.append(Modifier.toString(getModifiers())); 129 130 if(0 != modifiers) 131 sb.append(' '); 132 133 if(isVarArgs()) 134 sb.append(typename.replaceFirst("\\[\\]$", "...")); 135 else 136 sb.append(typename); 137 138 sb.append(' '); 139 sb.append(getName()); 140 141 return sb.toString(); 142 } 263 */ 264 public boolean isSynthetic() { 265 return Modifier.isSynthetic(getModifiers()); 266 } 267 268 /** 269 * Returns {@code true} if this parameter represents a variable 270 * argument list; returns {@code false} otherwise. 271 * 272 * @return {@code true} if an only if this parameter represents a 273 * variable argument list. 274 */ 275 public boolean isVarArgs() { 276 return executable.isVarArgs() && 277 index == executable.getParameterCount() - 1; 278 } 279 280 281 /** 282 * {@inheritDoc} 283 * @throws NullPointerException {@inheritDoc} 284 */ 285 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 286 Objects.requireNonNull(annotationClass); 287 return annotationClass.cast(declaredAnnotations().get(annotationClass)); 288 } 289 290 /** 291 * {@inheritDoc} 292 * @throws NullPointerException {@inheritDoc} 293 */ 294 @Override 295 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { 296 Objects.requireNonNull(annotationClass); 297 298 return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass); 299 } 300 301 /** 302 * {@inheritDoc} 303 */ 304 public Annotation[] getDeclaredAnnotations() { 305 return executable.getParameterAnnotations()[index]; 306 } 307 308 /** 309 * @throws NullPointerException {@inheritDoc} 310 */ 311 public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { 312 // Only annotations on classes are inherited, for all other 313 // objects getDeclaredAnnotation is the same as 314 // getAnnotation. 315 return getAnnotation(annotationClass); 316 } 317 318 /** 319 * @throws NullPointerException {@inheritDoc} 320 */ 321 @Override 322 public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { 323 // Only annotations on classes are inherited, for all other 324 // objects getDeclaredAnnotations is the same as 325 // getAnnotations. 326 return getAnnotationsByType(annotationClass); 327 } 328 329 /** 330 * {@inheritDoc} 331 */ 332 public Annotation[] getAnnotations() { 333 return getDeclaredAnnotations(); 334 } 335 336 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; 337 338 private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { 339 if(null == declaredAnnotations) { 340 declaredAnnotations = new HashMap<>(); 341 for (Annotation a : getDeclaredAnnotations()) 342 declaredAnnotations.put(a.annotationType(), a); 343 } 344 return declaredAnnotations; 345 } 346 347 } | 58 * @param modifiers The modifier flags for the parameter. 59 * @param executable The executable which defines this parameter. 60 * @param index The index of the parameter. 61 */ 62 Parameter(String name, 63 int modifiers, 64 Executable executable, 65 int index) { 66 this.name = name; 67 this.modifiers = modifiers; 68 this.executable = executable; 69 this.index = index; 70 } 71 72 /** 73 * Compares based on the executable and the index. 74 * 75 * @param obj The object to compare. 76 * @return Whether or not this is equal to the argument. 77 */ 78 @Override 79 public boolean equals(Object obj) { 80 if(obj instanceof Parameter) { 81 Parameter other = (Parameter)obj; 82 return (other.executable.equals(executable) && 83 other.index == index); 84 } 85 return false; 86 } 87 88 /** 89 * Returns a hash code based on the executable's hash code and the 90 * index. 91 * 92 * @return A hash code based on the executable's hash code. 93 */ 94 @Override 95 public int hashCode() { 96 return executable.hashCode() ^ index; 97 } 98 99 /** 100 * Returns true if the parameter has a name according to the class 101 * file; returns false otherwise. Whether a parameter has a name 102 * is determined by the {@literal MethodParameters} attribute of 103 * the method which declares the parameter. 104 * 105 * @return true if and only if the parameter has a name according 106 * to the class file. 107 */ 108 public boolean isNamePresent() { 109 return executable.hasRealParameterData() && name != null; 110 } 111 112 /** 113 * Returns a string describing this parameter. The format is the 114 * modifiers for the parameter, if any, in canonical order as 115 * recommended by <cite>The Java™ Language 116 * Specification</cite>, followed by the fully- qualified type of 117 * the parameter (excluding the last [] if the parameter is 118 * variable arity), followed by "..." if the parameter is variable 119 * arity, followed by a space, followed by the name of the 120 * parameter. 121 * 122 * @return A string representation of the parameter and associated 123 * information. 124 */ 125 @Override 126 public String toString() { 127 final StringBuilder sb = new StringBuilder(); 128 final Type type = getParameterizedType(); 129 final String typename = type.getTypeName(); 130 131 sb.append(Modifier.toString(getModifiers())); 132 133 if(0 != modifiers) 134 sb.append(' '); 135 136 if(isVarArgs()) 137 sb.append(typename.replaceFirst("\\[\\]$", "...")); 138 else 139 sb.append(typename); 140 141 sb.append(' '); 142 sb.append(getName()); 143 144 return sb.toString(); 145 } 266 */ 267 public boolean isSynthetic() { 268 return Modifier.isSynthetic(getModifiers()); 269 } 270 271 /** 272 * Returns {@code true} if this parameter represents a variable 273 * argument list; returns {@code false} otherwise. 274 * 275 * @return {@code true} if an only if this parameter represents a 276 * variable argument list. 277 */ 278 public boolean isVarArgs() { 279 return executable.isVarArgs() && 280 index == executable.getParameterCount() - 1; 281 } 282 283 284 /** 285 * {@inheritDoc} 286 * <p>Note that any annotation returned by this method is a 287 * declaration annotation. 288 * @throws NullPointerException {@inheritDoc} 289 */ 290 @Override 291 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 292 Objects.requireNonNull(annotationClass); 293 return annotationClass.cast(declaredAnnotations().get(annotationClass)); 294 } 295 296 /** 297 * {@inheritDoc} 298 * <p>Note that any annotations returned by this method are 299 * declaration annotations. 300 * 301 * @throws NullPointerException {@inheritDoc} 302 */ 303 @Override 304 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { 305 Objects.requireNonNull(annotationClass); 306 307 return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass); 308 } 309 310 /** 311 * {@inheritDoc} 312 * <p>Note that any annotations returned by this method are 313 * declaration annotations. 314 */ 315 @Override 316 public Annotation[] getDeclaredAnnotations() { 317 return executable.getParameterAnnotations()[index]; 318 } 319 320 /** 321 * {@inheritDoc} 322 * <p>Note that any annotation returned by this method is a 323 * declaration annotation. 324 * 325 * @throws NullPointerException {@inheritDoc} 326 */ 327 @Override 328 public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { 329 // Only annotations on classes are inherited, for all other 330 // objects getDeclaredAnnotation is the same as 331 // getAnnotation. 332 return getAnnotation(annotationClass); 333 } 334 335 /** 336 * {@inheritDoc} 337 * <p>Note that any annotations returned by this method are 338 * declaration annotations. 339 * 340 * @throws NullPointerException {@inheritDoc} 341 */ 342 @Override 343 public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { 344 // Only annotations on classes are inherited, for all other 345 // objects getDeclaredAnnotations is the same as 346 // getAnnotations. 347 return getAnnotationsByType(annotationClass); 348 } 349 350 /** 351 * {@inheritDoc} 352 * <p>Note that any annotations returned by this method are 353 * declaration annotations. 354 */ 355 @Override 356 public Annotation[] getAnnotations() { 357 return getDeclaredAnnotations(); 358 } 359 360 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; 361 362 private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { 363 if(null == declaredAnnotations) { 364 declaredAnnotations = new HashMap<>(); 365 for (Annotation a : getDeclaredAnnotations()) 366 declaredAnnotations.put(a.annotationType(), a); 367 } 368 return declaredAnnotations; 369 } 370 371 } |