001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.reflect; 014 015import static org.apache.juneau.internal.StringUtils.*; 016 017import java.lang.annotation.*; 018import java.lang.reflect.*; 019import java.util.*; 020 021import org.apache.juneau.*; 022import org.apache.juneau.internal.*; 023 024/** 025 * Contains common methods between {@link ConstructorInfo} and {@link MethodInfo}. 026 */ 027public abstract class ExecutableInfo { 028 029 final ClassInfo declaringClass; 030 final Executable e, re; 031 final boolean isConstructor; 032 033 private ParamInfo[] params; 034 private ClassInfo[] paramTypes, exceptionInfos; 035 private Class<?>[] rawParamTypes, rawExceptionTypes; 036 private Type[] rawGenericParamTypes; 037 private Parameter[] rawParameters; 038 039 /** 040 * Constructor. 041 * 042 * @param declaringClass The class that declares this method or constructor. 043 * @param e The constructor or method that this info represents. 044 * @param re The "real" constructor if the constructor above is defined against a CGLIB proxy. 045 */ 046 protected ExecutableInfo(ClassInfo declaringClass, Executable e, Executable re) { 047 this.declaringClass = declaringClass; 048 this.e = e; 049 this.re = re == null ? e : re; 050 this.isConstructor = e instanceof Constructor; 051 } 052 053 /** 054 * Returns metadata about the class that declared this method or constructor. 055 * 056 * @return Metadata about the class that declared this method or constructor. 057 */ 058 public final ClassInfo getDeclaringClass() { 059 return declaringClass; 060 } 061 062 /** 063 * Returns <jk>true</jk> if this executable represents a {@link Constructor}. 064 * 065 * @return 066 * <jk>true</jk> if this executable represents a {@link Constructor} and can be cast to {@link ConstructorInfo}. 067 * <jk>false</jk> if this executable represents a {@link Method} and can be cast to {@link MethodInfo}. 068 */ 069 public final boolean isConstructor() { 070 return isConstructor; 071 } 072 073 //----------------------------------------------------------------------------------------------------------------- 074 // Parameters 075 //----------------------------------------------------------------------------------------------------------------- 076 077 /** 078 * Returns the number of parameters in this executable. 079 * 080 * <p> 081 * Same as calling {@link Executable#getParameterCount()}. 082 * 083 * @return The number of parameters in this executable. 084 */ 085 public final int getParamCount() { 086 return e.getParameterCount(); 087 } 088 089 /** 090 * Returns <jk>true</jk> if this executable has at least one parameter. 091 * 092 * <p> 093 * Same as calling {@link Executable#getParameterCount()} and comparing with zero. 094 * 095 * @return <jk>true</jk> if this executable has at least one parameter. 096 */ 097 public final boolean hasParams() { 098 return getParamCount() != 0; 099 } 100 101 /** 102 * Returns <jk>true</jk> if this executable has no parameters. 103 * 104 * <p> 105 * Same as calling {@link Executable#getParameterCount()} and comparing with zero. 106 * 107 * @return <jk>true</jk> if this executable has no parameters. 108 */ 109 public final boolean hasNoParams() { 110 return getParamCount() == 0; 111 } 112 113 /** 114 * Returns <jk>true</jk> if this executable has this number of arguments. 115 * 116 * <p> 117 * Same as calling {@link Executable#getParameterCount()} and comparing the count. 118 * 119 * @param number The number of expected arguments. 120 * @return <jk>true</jk> if this executable has this number of arguments. 121 */ 122 public final boolean hasNumParams(int number) { 123 return getParamCount() == number; 124 } 125 126 /** 127 * Returns the parameters defined on this executable. 128 * 129 * <p> 130 * Same as calling {@link Executable#getParameters()} but wraps the results 131 * 132 * @return An array of parameter information, never <jk>null</jk>. 133 */ 134 public final List<ParamInfo> getParams() { 135 return new UnmodifiableArray<>(_getParams()); 136 } 137 138 /** 139 * Returns parameter information at the specified index. 140 * 141 * @param index The parameter index. 142 * @return The parameter information, never <jk>null</jk>. 143 */ 144 public final ParamInfo getParam(int index) { 145 checkIndex(index); 146 return _getParams()[index]; 147 } 148 149 /** 150 * Returns the parameter types on this executable. 151 * 152 * @return The parameter types on this executable. 153 */ 154 public final List<ClassInfo> getParamTypes() { 155 return new UnmodifiableArray<>(_getParamTypes()); 156 } 157 158 /** 159 * Returns the parameter type of the parameter at the specified index. 160 * 161 * @param index The parameter index. 162 * @return The parameter type of the parameter at the specified index. 163 */ 164 public final ClassInfo getParamType(int index) { 165 checkIndex(index); 166 return _getParamTypes()[index]; 167 } 168 169 /** 170 * Returns the raw parameter types on this executable. 171 * 172 * @return The raw parameter types on this executable. 173 */ 174 public final List<Class<?>> getRawParamTypes() { 175 return new UnmodifiableArray<>(_getRawParamTypes()); 176 } 177 178 /** 179 * Returns the raw parameter type of the parameter at the specified index. 180 * 181 * @param index The parameter index. 182 * @return The raw parameter type of the parameter at the specified index. 183 */ 184 public final Class<?> getRawParamType(int index) { 185 checkIndex(index); 186 return _getRawParamTypes()[index]; 187 } 188 189 /** 190 * Returns the raw generic parameter types on this executable. 191 * 192 * @return The raw generic parameter types on this executable. 193 */ 194 public final List<Type> getRawGenericParamTypes() { 195 return new UnmodifiableArray<>(_getRawGenericParamTypes()); 196 } 197 198 /** 199 * Returns the raw generic parameter type of the parameter at the specified index. 200 * 201 * @param index The parameter index. 202 * @return The raw generic parameter type of the parameter at the specified index. 203 */ 204 public final Type getRawGenericParamType(int index) { 205 checkIndex(index); 206 return _getRawGenericParamTypes()[index]; 207 } 208 209 /** 210 * Returns an array of raw {@link Parameter} objects that represent all the parameters to the underlying executable represented by this object. 211 * 212 * @return An array of raw {@link Parameter} objects, or an empty array if executable has no parameters. 213 * @see Executable#getParameters() 214 */ 215 public final List<Parameter> getRawParameters() { 216 return new UnmodifiableArray<>(_getRawParameters()); 217 } 218 219 /** 220 * Returns the raw {@link Parameter} object that represents the parameter at the specified index. 221 * 222 * @param index The parameter index. 223 * @return The raw {@link Parameter} object that represents the parameter at the specified index. 224 * @see Executable#getParameters() 225 */ 226 public final Parameter getRawParameter(int index) { 227 checkIndex(index); 228 return _getRawParameters()[index]; 229 } 230 231 private ParamInfo[] _getParams() { 232 if (params == null) { 233 Parameter[] rp = _getRawParameters(); 234 ParamInfo[] l = new ParamInfo[rp.length]; 235 for (int i = 0; i < rp.length; i++) 236 l[i] = new ParamInfo(this, rp[i], i); 237 params = l; 238 } 239 return params; 240 } 241 242 private ClassInfo[] _getParamTypes() { 243 if (paramTypes == null) { 244 Class<?>[] ptc = _getRawParamTypes(); 245 // Note that due to a bug involving Enum constructors, getGenericParameterTypes() may 246 // always return an empty array. This appears to be fixed in Java 8 b75. 247 Type[] ptt = _getRawGenericParamTypes(); 248 if (ptt.length != ptc.length) 249 ptt = ptc; 250 ClassInfo[] l = new ClassInfo[ptc.length]; 251 for (int i = 0; i < ptc.length; i++) 252 l[i] = ClassInfo.of(ptc[i], ptt[i]); 253 paramTypes = l; 254 } 255 return paramTypes; 256 } 257 258 Class<?>[] _getRawParamTypes() { 259 if (rawParamTypes == null) 260 rawParamTypes = e.getParameterTypes(); 261 return rawParamTypes; 262 } 263 264 private Type[] _getRawGenericParamTypes() { 265 if (rawGenericParamTypes == null) 266 rawGenericParamTypes = re.getGenericParameterTypes(); 267 return rawGenericParamTypes; 268 } 269 270 private Parameter[] _getRawParameters() { 271 if (rawParameters == null) 272 rawParameters = re.getParameters(); 273 return rawParameters; 274 } 275 276 private void checkIndex(int index) { 277 int pc = getParamCount(); 278 if (pc == 0) 279 throw new IndexOutOfBoundsException(format("Invalid index ''{0}''. No parameters.", index)); 280 if (index < 0 || index >= pc) 281 throw new IndexOutOfBoundsException(format("Invalid index ''{0}''. Parameter count: {1}", index, pc)); 282 } 283 284 //----------------------------------------------------------------------------------------------------------------- 285 // Annotations 286 //----------------------------------------------------------------------------------------------------------------- 287 288 /** 289 * Returns the parameter annotations on this executable. 290 * 291 * @return The parameter annotations on this executable. 292 */ 293 public final Annotation[][] getParameterAnnotations() { 294 return e.getParameterAnnotations(); 295 } 296 297 /** 298 * Returns the parameter annotations on the parameter at the specified index. 299 * 300 * @param index The parameter index. 301 * @return The parameter annotations on the parameter at the specified index. 302 */ 303 public final Annotation[] getParameterAnnotations(int index) { 304 checkIndex(index); 305 return e.getParameterAnnotations()[index]; 306 } 307 308 //----------------------------------------------------------------------------------------------------------------- 309 // Exceptions 310 //----------------------------------------------------------------------------------------------------------------- 311 312 /** 313 * Returns the exception types on this executable. 314 * 315 * @return The exception types on this executable. 316 */ 317 public final List<ClassInfo> getExceptionTypes() { 318 return new UnmodifiableArray<>(_getExceptionTypes()); 319 } 320 321 /** 322 * Returns the raw exception types on this executable. 323 * 324 * @return The raw exception types on this executable. 325 */ 326 public final Class<?>[] getRawExceptionTypes() { 327 return _getRawExceptionTypes().clone(); 328 } 329 330 private ClassInfo[] _getExceptionTypes() { 331 if (exceptionInfos == null) { 332 Class<?>[] exceptionTypes = _getRawExceptionTypes(); 333 ClassInfo[] l = new ClassInfo[exceptionTypes.length]; 334 for (int i = 0; i < exceptionTypes.length; i++) 335 l[i] = ClassInfo.of(exceptionTypes[i]); 336 exceptionInfos = l; 337 } 338 return exceptionInfos; 339 } 340 341 private Class<?>[] _getRawExceptionTypes() { 342 if (rawExceptionTypes == null) 343 rawExceptionTypes = e.getExceptionTypes(); 344 return rawExceptionTypes; 345 } 346 347 //----------------------------------------------------------------------------------------------------------------- 348 // Characteristics 349 //----------------------------------------------------------------------------------------------------------------- 350 351 /** 352 * Returns <jk>true</jk> if all specified flags are applicable to this method. 353 * 354 * @param flags The flags to test for. 355 * @return <jk>true</jk> if all specified flags are applicable to this method. 356 */ 357 public final boolean isAll(ReflectFlags...flags) { 358 for (ReflectFlags f : flags) { 359 switch (f) { 360 case DEPRECATED: 361 if (isNotDeprecated()) 362 return false; 363 break; 364 case NOT_DEPRECATED: 365 if (isDeprecated()) 366 return false; 367 break; 368 case HAS_PARAMS: 369 if (hasNoParams()) 370 return false; 371 break; 372 case HAS_NO_PARAMS: 373 if (hasParams()) 374 return false; 375 break; 376 case PUBLIC: 377 if (isNotPublic()) 378 return false; 379 break; 380 case NOT_PUBLIC: 381 if (isPublic()) 382 return false; 383 break; 384 case STATIC: 385 if (isNotStatic()) 386 return false; 387 break; 388 case NOT_STATIC: 389 if (isStatic()) 390 return false; 391 break; 392 case ABSTRACT: 393 if (isNotAbstract()) 394 return false; 395 break; 396 case NOT_ABSTRACT: 397 if (isAbstract()) 398 return false; 399 break; 400 default: 401 throw new RuntimeException("Invalid flag for executable: " + f); 402 } 403 } 404 return true; 405 } 406 407 /** 408 * Returns <jk>true</jk> if all specified flags are applicable to this method. 409 * 410 * @param flags The flags to test for. 411 * @return <jk>true</jk> if all specified flags are applicable to this method. 412 */ 413 public final boolean isAny(ReflectFlags...flags) { 414 for (ReflectFlags f : flags) { 415 switch (f) { 416 case DEPRECATED: 417 if (isDeprecated()) 418 return true; 419 break; 420 case NOT_DEPRECATED: 421 if (isNotDeprecated()) 422 return true; 423 break; 424 case HAS_PARAMS: 425 if (hasParams()) 426 return true; 427 break; 428 case HAS_NO_PARAMS: 429 if (hasNoParams()) 430 return true; 431 break; 432 case PUBLIC: 433 if (isPublic()) 434 return true; 435 break; 436 case NOT_PUBLIC: 437 if (isNotPublic()) 438 return true; 439 break; 440 case STATIC: 441 if (isStatic()) 442 return true; 443 break; 444 case NOT_STATIC: 445 if (isNotStatic()) 446 return true; 447 break; 448 case ABSTRACT: 449 if (isAbstract()) 450 return true; 451 break; 452 case NOT_ABSTRACT: 453 if (isNotAbstract()) 454 return true; 455 break; 456 default: 457 throw new RuntimeException("Invalid flag for executable: " + f); 458 } 459 } 460 return false; 461 } 462 463 /** 464 * Returns <jk>true</jk> if this method has the specified arguments. 465 * 466 * @param args The arguments to test for. 467 * @return <jk>true</jk> if this method has this arguments in the exact order. 468 */ 469 public final boolean hasParamTypes(Class<?>...args) { 470 Class<?>[] pt = _getRawParamTypes(); 471 if (pt.length == args.length) { 472 for (int i = 0; i < pt.length; i++) 473 if (! pt[i].equals(args[i])) 474 return false; 475 return true; 476 } 477 return false; 478 } 479 480 /** 481 * Returns <jk>true</jk> if this method has the specified arguments. 482 * 483 * @param args The arguments to test for. 484 * @return <jk>true</jk> if this method has this arguments in the exact order. 485 */ 486 public final boolean hasParamTypes(ClassInfo...args) { 487 Class<?>[] pt = _getRawParamTypes(); 488 if (pt.length == args.length) { 489 for (int i = 0; i < pt.length; i++) 490 if (! pt[i].equals(args[i].inner())) 491 return false; 492 return true; 493 } 494 return false; 495 } 496 497 /** 498 * Returns <jk>true</jk> if this method has the specified argument parent classes. 499 * 500 * @param args The arguments to test for. 501 * @return <jk>true</jk> if this method has this arguments in the exact order. 502 */ 503 public final boolean hasMatchingParamTypes(Class<?>...args) { 504 ClassInfo[] pt = _getParamTypes(); 505 if (pt.length != args.length) 506 return false; 507 for (int i = 0; i < pt.length; i++) { 508 boolean matched = false; 509 for (int j = 0; j < args.length; j++) 510 if (pt[i].isParentOfFuzzyPrimitives(args[j])) 511 matched = true; 512 if (! matched) 513 return false; 514 } 515 return true; 516 } 517 518 /** 519 * Returns <jk>true</jk> if this method has the specified argument parent classes. 520 * 521 * @param args The arguments to test for. 522 * @return <jk>true</jk> if this method has this arguments in the exact order. 523 */ 524 public final boolean hasMatchingParamTypes(ClassInfo...args) { 525 ClassInfo[] pt = _getParamTypes(); 526 if (pt.length != args.length) 527 return false; 528 for (int i = 0; i < pt.length; i++) { 529 boolean matched = false; 530 for (int j = 0; j < args.length; j++) 531 if (pt[i].isParentOfFuzzyPrimitives(args[j].inner())) 532 matched = true; 533 if (! matched) 534 return false; 535 } 536 return true; 537 } 538 539 /** 540 * Returns <jk>true</jk> if this method has at most only this arguments in any order. 541 * 542 * @param args The arguments to test for. 543 * @return <jk>true</jk> if this method has at most only this arguments in any order. 544 */ 545 public final boolean hasFuzzyParamTypes(Class<?>...args) { 546 return fuzzyArgsMatch(args) != -1; 547 } 548 549 /** 550 * Returns how well this method matches the specified arg types. 551 * 552 * <p> 553 * The number returned is the number of method arguments that match the passed in arg types. 554 * <br>Returns <c>-1</c> if the method cannot take in one or more of the specified arguments. 555 * 556 * @param argTypes The arg types to check against. 557 * @return How many parameters match or <c>-1</c> if method cannot handle one or more of the arguments. 558 */ 559 public int fuzzyArgsMatch(Class<?>... argTypes) { 560 int matches = 0; 561 outer: for (ClassInfo pi : getParamTypes()) { 562 for (Class<?> a : argTypes) { 563 if (pi.isParentOfFuzzyPrimitives(a)) { 564 matches++; 565 continue outer; 566 } 567 } 568 return -1; 569 } 570 return matches; 571 } 572 573 574 /** 575 * Returns <jk>true</jk> if this method has at most only this arguments in any order. 576 * 577 * @param args The arguments to test for. 578 * @return <jk>true</jk> if this method has at most only this arguments in any order. 579 */ 580 public boolean hasFuzzyParamTypes(ClassInfo...args) { 581 return fuzzyArgsMatch(args) != -1; 582 } 583 584 /** 585 * Returns how well this method matches the specified arg types. 586 * 587 * <p> 588 * The number returned is the number of method arguments that match the passed in arg types. 589 * <br>Returns <c>-1</c> if the method cannot take in one or more of the specified arguments. 590 * 591 * @param argTypes The arg types to check against. 592 * @return How many parameters match or <c>-1</c> if method cannot handle one or more of the arguments. 593 */ 594 public int fuzzyArgsMatch(ClassInfo... argTypes) { 595 int matches = 0; 596 outer: for (ClassInfo pi : getParamTypes()) { 597 for (ClassInfo a : argTypes) { 598 if (pi.isParentOfFuzzyPrimitives(a)) { 599 matches++; 600 continue outer; 601 } 602 } 603 return -1; 604 } 605 return matches; 606 } 607 608 /** 609 * Returns <jk>true</jk> if this method has the {@link Deprecated @Deprecated} annotation on it. 610 * 611 * @return <jk>true</jk> if this method has the {@link Deprecated @Deprecated} annotation on it. 612 */ 613 public final boolean isDeprecated() { 614 return e.isAnnotationPresent(Deprecated.class); 615 616 } 617 618 /** 619 * Returns <jk>true</jk> if this method doesn't have the {@link Deprecated @Deprecated} annotation on it. 620 * 621 * @return <jk>true</jk> if this method doesn't have the {@link Deprecated @Deprecated} annotation on it. 622 */ 623 public final boolean isNotDeprecated() { 624 return ! e.isAnnotationPresent(Deprecated.class); 625 626 } 627 628 /** 629 * Returns <jk>true</jk> if this method is abstract. 630 * 631 * @return <jk>true</jk> if this method is abstract. 632 */ 633 public final boolean isAbstract() { 634 return Modifier.isAbstract(e.getModifiers()); 635 } 636 637 /** 638 * Returns <jk>true</jk> if this method is not abstract. 639 * 640 * @return <jk>true</jk> if this method is not abstract. 641 */ 642 public final boolean isNotAbstract() { 643 return ! Modifier.isAbstract(e.getModifiers()); 644 } 645 646 /** 647 * Returns <jk>true</jk> if this method is public. 648 * 649 * @return <jk>true</jk> if this method is public. 650 */ 651 public final boolean isPublic() { 652 return Modifier.isPublic(e.getModifiers()); 653 } 654 655 /** 656 * Returns <jk>true</jk> if this method is not public. 657 * 658 * @return <jk>true</jk> if this method is not public. 659 */ 660 public final boolean isNotPublic() { 661 return ! Modifier.isPublic(e.getModifiers()); 662 } 663 664 /** 665 * Returns <jk>true</jk> if this method is static. 666 * 667 * @return <jk>true</jk> if this method is static. 668 */ 669 public final boolean isStatic() { 670 return Modifier.isStatic(e.getModifiers()); 671 } 672 673 /** 674 * Returns <jk>true</jk> if this method is not static. 675 * 676 * @return <jk>true</jk> if this method is not static. 677 */ 678 public final boolean isNotStatic() { 679 return ! Modifier.isStatic(e.getModifiers()); 680 } 681 682 //----------------------------------------------------------------------------------------------------------------- 683 // Visibility 684 //----------------------------------------------------------------------------------------------------------------- 685 686 /** 687 * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions. 688 * 689 * @return This object (for method chaining). 690 */ 691 @FluentSetter 692 public ExecutableInfo accessible() { 693 setAccessible(); 694 return this; 695 } 696 697 /** 698 * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions. 699 * 700 * @return <jk>true</jk> if call was successful. 701 */ 702 public final boolean setAccessible() { 703 try { 704 if (! (e.isAccessible())) 705 e.setAccessible(true); 706 return true; 707 } catch (SecurityException e) { 708 return false; 709 } 710 } 711 712 /** 713 * Identifies if the specified visibility matches this method. 714 * 715 * @param v The visibility to validate against. 716 * @return <jk>true</jk> if this visibility matches the modifier attribute of this method. 717 */ 718 public final boolean isVisible(Visibility v) { 719 return v.isVisible(e); 720 } 721 722 //----------------------------------------------------------------------------------------------------------------- 723 // Labels 724 //----------------------------------------------------------------------------------------------------------------- 725 726 /** 727 * Returns <jk>true</jk> if this method has this name. 728 * 729 * @param name The name to test for. 730 * @return <jk>true</jk> if this method has this name. 731 */ 732 public final boolean hasName(String name) { 733 return getSimpleName().equals(name); 734 } 735 736 /** 737 * Returns <jk>true</jk> if this method has a name in the specified list. 738 * 739 * @param names The names to test for. 740 * @return <jk>true</jk> if this method has one of the names. 741 */ 742 public final boolean hasName(String...names) { 743 for (String n : names) 744 if (getSimpleName().equals(n)) 745 return true; 746 return false; 747 } 748 749 /** 750 * Returns <jk>true</jk> if this method has a name in the specified set. 751 * 752 * @param names The names to test for. 753 * @return <jk>true</jk> if this method has one of the names. 754 */ 755 public final boolean hasName(Set<String> names) { 756 return names.contains(getSimpleName()); 757 } 758 759 //----------------------------------------------------------------------------------------------------------------- 760 // Labels 761 //----------------------------------------------------------------------------------------------------------------- 762 763 /** 764 * Returns the full name of this executable. 765 * 766 * <h5 class='section'>Examples:</h5> 767 * <ul> 768 * <li><js>"com.foo.MyClass.get(java.util.String)"</js> - Method. 769 * <li><js>"com.foo.MyClass(java.util.String)"</js> - Constructor. 770 * </ul> 771 * 772 * @return The underlying executable name. 773 */ 774 public final String getFullName() { 775 StringBuilder sb = new StringBuilder(128); 776 ClassInfo dc = declaringClass; 777 Package p = dc.getPackage(); 778 if (p != null) 779 sb.append(p.getName()).append('.'); 780 dc.appendShortName(sb); 781 if (! isConstructor) 782 sb.append('.').append(getSimpleName()); 783 sb.append('('); 784 List<ClassInfo> pt = getParamTypes(); 785 for (int i = 0; i < pt.size(); i++) { 786 if (i > 0) 787 sb.append(','); 788 pt.get(i).appendFullName(sb); 789 } 790 sb.append(')'); 791 return sb.toString(); 792 } 793 794 /** 795 * Returns the short name of this executable. 796 * 797 * <h5 class='section'>Examples:</h5> 798 * <ul> 799 * <li><js>"MyClass.get(String)"</js> - Method. 800 * <li><js>"MyClass(String)"</js> - Constructor. 801 * </ul> 802 * 803 * @return The underlying executable name. 804 */ 805 public final String getShortName() { 806 StringBuilder sb = new StringBuilder(64); 807 sb.append(getSimpleName()).append('('); 808 Class<?>[] pt = _getRawParamTypes(); 809 for (int i = 0; i < pt.length; i++) { 810 if (i > 0) 811 sb.append(','); 812 sb.append(pt[i].getSimpleName()); 813 } 814 sb.append(')'); 815 return sb.toString(); 816 } 817 818 /** 819 * Returns the simple name of the underlying method. 820 * 821 * @return The simple name of the underlying method; 822 */ 823 public final String getSimpleName() { 824 return isConstructor ? e.getDeclaringClass().getSimpleName() : e.getName(); 825 } 826 827 @Override 828 public String toString() { 829 return getShortName(); 830 } 831 832 // <FluentSetters> 833 834 // </FluentSetters> 835}