1 /* 2 * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javac.code; 27 28 import java.util.Collections; 29 import java.util.EnumSet; 30 import java.util.Map; 31 import java.util.Set; 32 import java.util.concurrent.ConcurrentHashMap; 33 34 import javax.lang.model.element.Modifier; 35 36 import com.sun.tools.javac.util.Assert; 37 import com.sun.tools.javac.util.StringUtils; 38 39 /** Access flags and other modifiers for Java classes and members. 40 * 41 * <p><b>This is NOT part of any supported API. 42 * If you write code that depends on this, you do so at your own risk. 43 * This code and its internal interfaces are subject to change or 44 * deletion without notice.</b> 45 */ 46 public class Flags { 47 48 private Flags() {} // uninstantiable 49 50 public static String toString(long flags) { 51 StringBuilder buf = new StringBuilder(); 52 String sep = ""; 53 for (Flag flag : asFlagSet(flags)) { 54 buf.append(sep); 55 buf.append(flag); 56 sep = " "; 57 } 58 return buf.toString(); 59 } 60 61 public static EnumSet<Flag> asFlagSet(long flags) { 62 EnumSet<Flag> flagSet = EnumSet.noneOf(Flag.class); 63 for (Flag flag : Flag.values()) { 64 if ((flags & flag.value) != 0) { 65 flagSet.add(flag); 66 flags &= ~flag.value; 67 } 68 } 69 Assert.check(flags == 0); 70 return flagSet; 71 } 72 73 /* Standard Java flags. 74 */ 75 public static final int PUBLIC = 1; 76 public static final int PRIVATE = 1<<1; 77 public static final int PROTECTED = 1<<2; 78 public static final int STATIC = 1<<3; 79 public static final int FINAL = 1<<4; 80 public static final int SYNCHRONIZED = 1<<5; 81 public static final int VOLATILE = 1<<6; 82 public static final int TRANSIENT = 1<<7; 83 public static final int NATIVE = 1<<8; 84 public static final int INTERFACE = 1<<9; 85 public static final int ABSTRACT = 1<<10; 86 public static final int STRICTFP = 1<<11; 87 88 /* Flag that marks a symbol synthetic, added in classfile v49.0. */ 89 public static final int SYNTHETIC = 1<<12; 90 91 /** Flag that marks attribute interfaces, added in classfile v49.0. */ 92 public static final int ANNOTATION = 1<<13; 93 94 /** An enumeration type or an enumeration constant, added in 95 * classfile v49.0. */ 96 public static final int ENUM = 1<<14; 97 98 /** Added in SE8, represents constructs implicitly declared in source. */ 99 public static final int MANDATED = 1<<15; 100 101 /** Marks a type as a primitive class. We can't reuse the class file encoding (ACC_PRIMITIVE) 102 * since the latter shares its value (0x800) with ACC_STRICT (javac speak: STRICT_FP) and while 103 * STRICT_FP is not a valid flag for a class in the class file level, javac's ASTs flag a class 104 * as being STRICT_FP so as to propagate the FP strictness to methods of the class thereby causing 105 * a clash */ 106 public static final int PRIMITIVE_CLASS = 1<<16; 107 108 public static final int StandardFlags = 0x0fff; 109 110 // Because the following access flags are overloaded with other 111 // bit positions, we translate them when reading and writing class 112 // files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC, 113 // for example. 114 public static final int ACC_IDENTITY = 0x0020; 115 public static final int ACC_VALUE = 0x0040; 116 public static final int ACC_BRIDGE = 0x0040; 117 public static final int ACC_VARARGS = 0x0080; 118 public static final int ACC_PRIMITIVE = 0x0800; 119 public static final int ACC_MODULE = 0x8000; 120 121 /***************************************** 122 * Internal compiler flags (no bits in the lower 16). 123 *****************************************/ 124 125 /** Flag is set if symbol is deprecated. See also DEPRECATED_REMOVAL. 126 */ 127 public static final int DEPRECATED = 1<<17; 128 129 /** Flag is set for a variable symbol if the variable's definition 130 * has an initializer part. 131 */ 132 public static final int HASINIT = 1<<18; 133 134 /** Flag is set for a class symbol if it defines one or more non-empty 135 * instance initializer block(s). This is relevenat only for class symbols 136 * that originate from source types. For binary types the instance initializer 137 * blocks are "normalized" into the constructors. 138 */ 139 public static final int HASINITBLOCK = 1<<18; 140 141 /** Flag is set for a method symbol if it is an empty no-arg ctor. 142 * i.e. one that simply returns (jlO) or merely chains to a super's 143 * no-arg ctor 144 */ 145 public static final int EMPTYNOARGCONSTR = 1<<18; 146 147 /** Flag is set for a class or interface whose instances have identity 148 * i.e. class/interface declarations that are expressly declared with 149 * the modifier `identity' or (b) any concrete class not declared with the 150 * modifier `value' (c) abstract class not declared `value' but meets various 151 * stipulations (d) older class files with ACC_SUPER bit set 152 */ 153 public static final int IDENTITY_TYPE = 1<<19; 154 155 /** Flag is set for compiler-generated anonymous method symbols 156 * that `own' an initializer block. 157 */ 158 public static final int BLOCK = 1<<20; 159 160 /** Marks a type as a value class */ 161 public static final int VALUE_CLASS = 1<<21; 162 163 /** Flag is set for nested classes that do not access instance members 164 * or `this' of an outer class and therefore don't need to be passed 165 * a this$n reference. This value is currently set only for anonymous 166 * classes in superclass constructor calls. 167 * todo: use this value for optimizing away this$n parameters in 168 * other cases. 169 */ 170 public static final int NOOUTERTHIS = 1<<22; 171 172 /** Flag is set for package symbols if a package has a member or 173 * directory and therefore exists. 174 */ 175 public static final int EXISTS = 1<<23; 176 177 /** Flag is set for compiler-generated compound classes 178 * representing multiple variable bounds 179 */ 180 public static final int COMPOUND = 1<<24; 181 182 /** Flag is set for class symbols if a class file was found for this class. 183 */ 184 public static final int CLASS_SEEN = 1<<25; 185 186 /** Flag is set for class symbols if a source file was found for this 187 * class. 188 */ 189 public static final int SOURCE_SEEN = 1<<26; 190 191 /* State flags (are reset during compilation). 192 */ 193 194 /** Flag for class symbols is set and later re-set as a lock in 195 * Enter to detect cycles in the superclass/superinterface 196 * relations. Similarly for constructor call cycle detection in 197 * Attr. 198 */ 199 public static final int LOCKED = 1<<27; 200 201 /** Flag for class symbols is set and later re-set to indicate that a class 202 * has been entered but has not yet been attributed. 203 */ 204 public static final int UNATTRIBUTED = 1<<28; 205 206 /** Flag for synthesized default constructors of anonymous classes. 207 */ 208 public static final int ANONCONSTR = 1<<29; //non-class members 209 210 /** 211 * Flag to indicate the super classes of this ClassSymbol has been attributed. 212 */ 213 public static final int SUPER_OWNER_ATTRIBUTED = 1<<29; //ClassSymbols 214 215 /** Flag for class symbols to indicate it has been checked and found 216 * acyclic. 217 */ 218 public static final int ACYCLIC = 1<<30; 219 220 /** Flag that marks bridge methods. 221 */ 222 public static final long BRIDGE = 1L<<31; 223 224 /** Flag that marks formal parameters. 225 */ 226 public static final long PARAMETER = 1L<<33; 227 228 /** Flag that marks varargs methods. 229 */ 230 public static final long VARARGS = 1L<<34; 231 232 /** Flag for annotation type symbols to indicate it has been 233 * checked and found acyclic. 234 */ 235 public static final long ACYCLIC_ANN = 1L<<35; 236 237 /** Flag that marks a generated default constructor. 238 */ 239 public static final long GENERATEDCONSTR = 1L<<36; 240 241 /** Flag that marks a hypothetical method that need not really be 242 * generated in the binary, but is present in the symbol table to 243 * simplify checking for erasure clashes - also used for 292 poly sig methods. 244 */ 245 public static final long HYPOTHETICAL = 1L<<37; 246 247 /** 248 * Flag that marks an internal proprietary class. 249 */ 250 public static final long PROPRIETARY = 1L<<38; 251 252 /** 253 * Flag that marks a multi-catch parameter. 254 */ 255 public static final long UNION = 1L<<39; 256 257 /** 258 * Flags an erroneous TypeSymbol as viable for recovery. 259 * TypeSymbols only. 260 */ 261 public static final long RECOVERABLE = 1L<<40; 262 263 /** 264 * Flag that marks an 'effectively final' local variable. 265 */ 266 public static final long EFFECTIVELY_FINAL = 1L<<41; 267 268 /** 269 * Flag that marks non-override equivalent methods with the same signature, 270 * or a conflicting match binding (BindingSymbol). 271 */ 272 public static final long CLASH = 1L<<42; 273 274 /** 275 * Flag that marks either a default method or an interface containing default methods. 276 */ 277 public static final long DEFAULT = 1L<<43; 278 279 /** 280 * Flag that marks class as auxiliary, ie a non-public class following 281 * the public class in a source file, that could block implicit compilation. 282 */ 283 public static final long AUXILIARY = 1L<<44; 284 285 /** 286 * Flag that marks that a symbol is not available in the current profile 287 */ 288 public static final long NOT_IN_PROFILE = 1L<<45; 289 290 /** 291 * Flag that indicates that an override error has been detected by Check. 292 */ 293 public static final long BAD_OVERRIDE = 1L<<45; 294 295 /** 296 * Flag that indicates a signature polymorphic method (292). 297 */ 298 public static final long SIGNATURE_POLYMORPHIC = 1L<<46; 299 300 /** 301 * Flag that indicates that an inference variable is used in a 'throws' clause. 302 */ 303 public static final long THROWS = 1L<<47; 304 305 /** 306 * Flag that marks potentially ambiguous overloads 307 */ 308 public static final long POTENTIALLY_AMBIGUOUS = 1L<<48; 309 310 /** 311 * Flag that marks a synthetic method body for a lambda expression 312 */ 313 public static final long LAMBDA_METHOD = 1L<<49; 314 315 /** 316 * Flag to control recursion in TransTypes 317 */ 318 public static final long TYPE_TRANSLATED = 1L<<50; 319 320 /** 321 * Flag to indicate class symbol is for module-info 322 */ 323 public static final long MODULE = 1L<<51; 324 325 /** 326 * Flag to indicate the given ModuleSymbol is an automatic module. 327 */ 328 public static final long AUTOMATIC_MODULE = 1L<<52; //ModuleSymbols only 329 330 /** 331 * Flag to indicate the given PackageSymbol contains any non-.java and non-.class resources. 332 */ 333 public static final long HAS_RESOURCE = 1L<<52; //PackageSymbols only 334 335 /** 336 * Flag to indicate the given ParamSymbol has a user-friendly name filled. 337 */ 338 public static final long NAME_FILLED = 1L<<52; //ParamSymbols only 339 340 /** 341 * Flag to indicate the given ModuleSymbol is a system module. 342 */ 343 public static final long SYSTEM_MODULE = 1L<<53; //ModuleSymbols only 344 345 /** 346 * Flag to indicate the given ClassSymbol is a value based. 347 */ 348 public static final long VALUE_BASED = 1L<<53; //ClassSymbols only 349 350 /** 351 * Flag to indicate the given symbol has a @Deprecated annotation. 352 */ 353 public static final long DEPRECATED_ANNOTATION = 1L<<54; 354 355 /** 356 * Flag to indicate the given symbol has been deprecated and marked for removal. 357 */ 358 public static final long DEPRECATED_REMOVAL = 1L<<55; 359 360 /** 361 * Flag to indicate the API element in question is for a preview API. 362 */ 363 public static final long PREVIEW_API = 1L<<56; //any Symbol kind 364 365 /** 366 * Flag for synthesized default constructors of anonymous classes that have an enclosing expression. 367 */ 368 public static final long ANONCONSTR_BASED = 1L<<57; 369 370 /** 371 * Flag that marks finalize block as body-only, should not be copied into catch clauses. 372 * Used to implement try-with-resources. 373 */ 374 public static final long BODY_ONLY_FINALIZE = 1L<<17; //blocks only 375 376 /** 377 * Flag to indicate the API element in question is for a preview API. 378 */ 379 public static final long PREVIEW_REFLECTIVE = 1L<<58; //any Symbol kind 380 381 /** 382 * Flag to indicate the given variable is a match binding variable. 383 */ 384 public static final long MATCH_BINDING = 1L<<59; 385 386 /** 387 * A flag to indicate a match binding variable whose scope extends after the current statement. 388 */ 389 public static final long MATCH_BINDING_TO_OUTER = 1L<<60; 390 391 /** 392 * Flag to indicate that a class is a record. The flag is also used to mark fields that are 393 * part of the state vector of a record and to mark the canonical constructor 394 */ 395 public static final long RECORD = 1L<<61; // ClassSymbols, MethodSymbols and VarSymbols 396 397 /** 398 * Flag to mark a record constructor as a compact one 399 */ 400 public static final long COMPACT_RECORD_CONSTRUCTOR = 1L<<51; // MethodSymbols only 401 402 /** 403 * Flag to mark a record field that was not initialized in the compact constructor 404 */ 405 public static final long UNINITIALIZED_FIELD= 1L<<51; // VarSymbols only 406 407 /** Flag is set for compiler-generated record members, it could be applied to 408 * accessors and fields 409 */ 410 public static final int GENERATED_MEMBER = 1<<24; // MethodSymbols and VarSymbols 411 412 /** 413 * Flag to indicate sealed class/interface declaration. 414 */ 415 public static final long SEALED = 1L<<62; // ClassSymbols 416 417 /** 418 * Flag to indicate that the class/interface was declared with the non-sealed modifier. 419 */ 420 public static final long NON_SEALED = 1L<<63; // ClassSymbols 421 422 423 /** Modifier masks. 424 */ 425 public static final int 426 AccessFlags = PUBLIC | PROTECTED | PRIVATE, 427 LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC | ACC_IDENTITY, 428 StaticLocalClassFlags = LocalClassFlags | STATIC | INTERFACE, 429 MemberClassFlags = LocalClassFlags | INTERFACE | AccessFlags, 430 MemberStaticClassFlags = MemberClassFlags | STATIC, 431 ClassFlags = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION, 432 InterfaceVarFlags = FINAL | STATIC | PUBLIC, 433 VarFlags = AccessFlags | FINAL | STATIC | 434 VOLATILE | TRANSIENT | ENUM, 435 ConstructorFlags = AccessFlags, 436 InterfaceMethodFlags = ABSTRACT | PUBLIC, 437 MethodFlags = AccessFlags | ABSTRACT | STATIC | NATIVE | 438 SYNCHRONIZED | FINAL | STRICTFP, 439 RecordMethodFlags = AccessFlags | ABSTRACT | STATIC | 440 SYNCHRONIZED | FINAL | STRICTFP, 441 AdjustedClassFlags = ClassFlags | ACC_PRIMITIVE | ACC_VALUE; 442 public static final long 443 ExtendedStandardFlags = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED | PRIMITIVE_CLASS | VALUE_CLASS, 444 ExtendedMemberClassFlags = (long)MemberClassFlags | SEALED | NON_SEALED | PRIMITIVE_CLASS | VALUE_CLASS, 445 ExtendedMemberStaticClassFlags = (long) MemberStaticClassFlags | SEALED | NON_SEALED | PRIMITIVE_CLASS | VALUE_CLASS, 446 ExtendedClassFlags = (long)ClassFlags | SEALED | NON_SEALED | PRIMITIVE_CLASS | VALUE_CLASS, 447 ExtendedLocalClassFlags = (long) LocalClassFlags | PRIMITIVE_CLASS | VALUE_CLASS, 448 ExtendedStaticLocalClassFlags = (long) StaticLocalClassFlags | PRIMITIVE_CLASS | VALUE_CLASS, 449 ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT | SEALED | NON_SEALED | PRIMITIVE_CLASS | VALUE_CLASS, 450 InterfaceMethodMask = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT, 451 AnnotationTypeElementMask = ABSTRACT | PUBLIC, 452 LocalVarFlags = FINAL | PARAMETER, 453 ReceiverParamFlags = PARAMETER; 454 455 public static Set<Modifier> asModifierSet(long flags) { 456 Set<Modifier> modifiers = modifierSets.get(flags); 457 if (modifiers == null) { 458 modifiers = java.util.EnumSet.noneOf(Modifier.class); 459 if (0 != (flags & PUBLIC)) modifiers.add(Modifier.PUBLIC); 460 if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED); 461 if (0 != (flags & PRIVATE)) modifiers.add(Modifier.PRIVATE); 462 if (0 != (flags & ABSTRACT)) modifiers.add(Modifier.ABSTRACT); 463 if (0 != (flags & STATIC)) modifiers.add(Modifier.STATIC); 464 if (0 != (flags & SEALED)) modifiers.add(Modifier.SEALED); 465 if (0 != (flags & NON_SEALED)) 466 modifiers.add(Modifier.NON_SEALED); 467 if (0 != (flags & FINAL)) modifiers.add(Modifier.FINAL); 468 if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT); 469 if (0 != (flags & VOLATILE)) modifiers.add(Modifier.VOLATILE); 470 if (0 != (flags & SYNCHRONIZED)) 471 modifiers.add(Modifier.SYNCHRONIZED); 472 if (0 != (flags & NATIVE)) modifiers.add(Modifier.NATIVE); 473 if (0 != (flags & STRICTFP)) modifiers.add(Modifier.STRICTFP); 474 if (0 != (flags & DEFAULT)) modifiers.add(Modifier.DEFAULT); 475 if (0 != (flags & PRIMITIVE_CLASS)) modifiers.add(Modifier.PRIMITIVE); 476 if (0 != (flags & VALUE_CLASS)) modifiers.add(Modifier.VALUE); 477 modifiers = Collections.unmodifiableSet(modifiers); 478 modifierSets.put(flags, modifiers); 479 } 480 return modifiers; 481 } 482 483 // Cache of modifier sets. 484 private static final Map<Long, Set<Modifier>> modifierSets = new ConcurrentHashMap<>(64); 485 486 public static boolean isStatic(Symbol symbol) { 487 return (symbol.flags() & STATIC) != 0; 488 } 489 490 public static boolean isEnum(Symbol symbol) { 491 return (symbol.flags() & ENUM) != 0; 492 } 493 494 public static boolean isConstant(Symbol.VarSymbol symbol) { 495 return symbol.getConstValue() != null; 496 } 497 498 499 public enum Flag { 500 PUBLIC(Flags.PUBLIC), 501 PRIVATE(Flags.PRIVATE), 502 PROTECTED(Flags.PROTECTED), 503 STATIC(Flags.STATIC), 504 FINAL(Flags.FINAL), 505 SYNCHRONIZED(Flags.SYNCHRONIZED), 506 VOLATILE(Flags.VOLATILE), 507 TRANSIENT(Flags.TRANSIENT), 508 NATIVE(Flags.NATIVE), 509 INTERFACE(Flags.INTERFACE), 510 ABSTRACT(Flags.ABSTRACT), 511 DEFAULT(Flags.DEFAULT), 512 STRICTFP(Flags.STRICTFP), 513 BRIDGE(Flags.BRIDGE), 514 SYNTHETIC(Flags.SYNTHETIC), 515 ANNOTATION(Flags.ANNOTATION), 516 DEPRECATED(Flags.DEPRECATED), 517 HASINIT(Flags.HASINIT), 518 HASINITBLOCK(Flags.HASINITBLOCK), 519 EMPTYNOARGCONSTR(Flags.EMPTYNOARGCONSTR), 520 IDENTITY_TYPE(Flags.IDENTITY_TYPE) { 521 @Override 522 public String toString() { 523 return "identity"; 524 } 525 }, 526 BLOCK(Flags.BLOCK), 527 ENUM(Flags.ENUM), 528 MANDATED(Flags.MANDATED), 529 PRIMITIVE(Flags.PRIMITIVE_CLASS), 530 VALUE(Flags.VALUE_CLASS), 531 NOOUTERTHIS(Flags.NOOUTERTHIS), 532 EXISTS(Flags.EXISTS), 533 COMPOUND(Flags.COMPOUND), 534 CLASS_SEEN(Flags.CLASS_SEEN), 535 SOURCE_SEEN(Flags.SOURCE_SEEN), 536 LOCKED(Flags.LOCKED), 537 UNATTRIBUTED(Flags.UNATTRIBUTED), 538 ANONCONSTR(Flags.ANONCONSTR), 539 ACYCLIC(Flags.ACYCLIC), 540 PARAMETER(Flags.PARAMETER), 541 VARARGS(Flags.VARARGS), 542 ACYCLIC_ANN(Flags.ACYCLIC_ANN), 543 GENERATEDCONSTR(Flags.GENERATEDCONSTR), 544 HYPOTHETICAL(Flags.HYPOTHETICAL), 545 PROPRIETARY(Flags.PROPRIETARY), 546 UNION(Flags.UNION), 547 EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL), 548 CLASH(Flags.CLASH), 549 AUXILIARY(Flags.AUXILIARY), 550 NOT_IN_PROFILE(Flags.NOT_IN_PROFILE), 551 BAD_OVERRIDE(Flags.BAD_OVERRIDE), 552 SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), 553 THROWS(Flags.THROWS), 554 LAMBDA_METHOD(Flags.LAMBDA_METHOD), 555 TYPE_TRANSLATED(Flags.TYPE_TRANSLATED), 556 MODULE(Flags.MODULE), 557 AUTOMATIC_MODULE(Flags.AUTOMATIC_MODULE), 558 SYSTEM_MODULE(Flags.SYSTEM_MODULE), 559 DEPRECATED_ANNOTATION(Flags.DEPRECATED_ANNOTATION), 560 DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL), 561 HAS_RESOURCE(Flags.HAS_RESOURCE), 562 POTENTIALLY_AMBIGUOUS(Flags.POTENTIALLY_AMBIGUOUS), 563 ANONCONSTR_BASED(Flags.ANONCONSTR_BASED), 564 NAME_FILLED(Flags.NAME_FILLED), 565 PREVIEW_API(Flags.PREVIEW_API), 566 PREVIEW_REFLECTIVE(Flags.PREVIEW_REFLECTIVE), 567 MATCH_BINDING(Flags.MATCH_BINDING), 568 MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER), 569 RECORD(Flags.RECORD), 570 RECOVERABLE(Flags.RECOVERABLE), 571 SEALED(Flags.SEALED), 572 NON_SEALED(Flags.NON_SEALED) { 573 @Override 574 public String toString() { 575 return "non-sealed"; 576 } 577 }; 578 579 Flag(long flag) { 580 this.value = flag; 581 this.lowercaseName = StringUtils.toLowerCase(name()); 582 } 583 584 @Override 585 public String toString() { 586 return lowercaseName; 587 } 588 589 final long value; 590 final String lowercaseName; 591 } 592 593 }