+ nestedClassName\ndef enclosingClass = Class.forName(enclosingClassName)\nClass nestedClass = null\nenclosingClass.declaredClasses.each\n{\n if (!nestedClass && fullNestedClassName.equals(it.name))\n {\n nestedClass = it\n }\n}\n\nif (nestedClass == null)\n{\n println \"Unable to find nested class ${fullNestedClassName}\"\n System.exit(-2)\n}\n\n\/\/ Use declaredMethods because don't care about inherited methods\nnestedClass.declaredMethods.each\n{\n print \"nMethod '${it.name}' \"\n print \"is ${getScopeModifier(it)} scope, \"\n print \"${it.synthetic ? 'is synthetic' : 'is NOT synthetic'}, and \"\n println \"${it.bridge ? 'is bridge' : 'is NOT bridge'}.\"\n}\n\n\ndef String getScopeModifier(Method method)\n{\n def modifiers = method.modifiers\n def isPrivate = Modifier.isPrivate(modifiers)\n def isPublic = Modifier.isPublic(modifiers)\n def isProtected = Modifier.isProtected(modifiers)\n String scopeString = \"package-private\" \/\/ default\n if (isPublic)\n {\n scopeString = \"public\"\n }\n else if (isProtected)\n {\n scopeString = \"protected\"\n }\n else if (isPrivate)\n {\n scopeString = \"private\"\n }\n return scopeString\n}\nWhen the above Groovy script is executed against the class and nested class shown above, the output is that shown in the next screen snapshot.The results of the Groovy script shown in the previous image verify what javap had already told us: there are four synthetic methods and one non-synthetic method defined on the nested class NestedClass. The script also tells us that the compiler-generated synthetic methods are package-private scope.The addition of synthetic methods to the nested class at package-private scope level is not the only thing the compiler did in the above example. It also changed the scope of the nested class itself from the private setting in code to package-private in the .class file. Indeed, while the synthetic methods were only added in the case where the enclosing class accessed the private attribute, the compiler always makes the nested class package-private even if it's specified as private in the code. The good news is that this is a resulting artifact of the compilation process, meaning that code cannot be compiled as-is against the changed scope level of the nested class or its synthetic methods. Runtime is where things can get dicey.The class, Rogue, attempts to access some of the NestedClass synthetic methods. Its source code is shown next, followed by the compiler error seen when trying to compile this Rogue source code.Rogue.java trying to access synthetic methods at compile timepackage dustin.examples;\n\nimport static java.lang.System.out;\n\npublic class Rogue\n{\n public static void main(final String[] arguments)\n {\n out.println(DemonstrateSyntheticMethods.NestedClass.getDate());\n }\n}\nThe above code will not compile, even for the non-synthetic method getDate(), and reports this error:Buildfile: C:javaexamplessyntheticbuild.xml\n\n-init:\n\ncompile:\n [javac] Compiling 1 source file to C:javaexamplessyntheticclasses\n [javac] C:javaexamplessyntheticsrcdustinexamplesRogue.java:9: dustin.examples.DemonstrateSyntheticMethods.NestedClass has private access in dustin.examples.DemonstrateSyntheticMethods\n [javac] out.println(DemonstrateSyntheticMethods.NestedClass.getDate());\n [javac] ^\n [javac] 1 error\n\nBUILD FAILED\nC:javaexamplessyntheticbuild.xml:29: Compile failed; see the compiler error output for details.\n\nTotal time: 1 second\nAs the above compilation error message indicates, even the non-synthetic method on the nested class is inaccessible at compile time because the nested class has private scope. In his article Java Insecurities: Accounting for Subtleties That Can Compromise Code, Charlie Lai discusses potential situations in which these compiler-introduced changes\u00a0are security vulnerabilities. Faisal Feroz goes further and states, in the post \u00a0How to Write Secure Java Code, \"Don\u2019t use Inner Classes\" (see\u00a0Nested, Inner, Member, and Top-Level Classes for details on inner classes as a subset of nested classes).Many of us can go for a long time in Java development without needing significant understanding of synthetic methods. However, there are situations when awareness of these is important. Besides security issues related to these, it is also to be aware of what they are when reading stack traces. Method names such as access$100, access$200, access$300, access$400, access$500, access$600, and access$1000 in the stack trace reflect synthetic methods generated by the compiler.Original Post Available at https:\/\/marxsoftware.blogspot.com\/.","wordCount":1555,"datePublished":"2010-10-18T10:01:00-04:00","dateModified":"2010-10-18T10:01:00-04:00","keywords":"Software Development,Groovy","mainEntityOfPage":"https:\/\/www.infoworld.com\/article\/2160402\/java-s-synthetic-methods.html"}]