Invoke private method with java.lang.invoke.MethodHandle - java

How can I invoke private method using method handles ?
As far as I can see there are only two kinds of publicly accessible Lookup instances:
MethodHandles.lookup()
MethodHandles.publicLookup()
and neither allows unrestricted private access.
There is the non-public Lookup.IMPL_LOOKUP that does what I want. Is there some public way to obtain it (assuming that SecurityManager allows it) ?

Turns out it's possible with Lookup#unreflect(Method) and temporarily making method accessible (potentially introducing small security issue unless done during program initialization).
Here is modified main method from Thorben's answer:
public static void main(String[] args) {
Lookup lookup = MethodHandles.lookup();
NestedTestClass ntc = new Program().new NestedTestClass();
try {
// Grab method using normal reflection and make it accessible
Method pm = NestedTestClass.class.getDeclaredMethod("gimmeTheAnswer");
pm.setAccessible(true);
// Now convert reflected method into method handle
MethodHandle pmh = lookup.unreflect(pm);
System.out.println("reflection:" + pm.invoke(ntc));
// We can now revoke access to original method
pm.setAccessible(false);
// And yet the method handle still works!
System.out.println("handle:" + pmh.invoke(ntc));
// While reflection is now denied again (throws exception)
System.out.println("reflection:" + pm.invoke(ntc));
} catch (Throwable e) {
e.printStackTrace();
}
}

I don't know, if this is what you really want. Perhaps you could give some more information about what you want to achieve with it.
But if you want to access Lookup.IMPL_LOOKUP, you can do it like in this code sample:
public class Main {
public static void main(String[] args) {
Lookup myLookup = MethodHandles.lookup(); // the Lookup which should be trusted
NestedTestClass ntc = new Main().new NestedTestClass(); // test class instance
try {
Field impl_lookup = Lookup.class.getDeclaredField("IMPL_LOOKUP"); // get the required field via reflections
impl_lookup.setAccessible(true); // set it accessible
Lookup lutrusted = (Lookup) impl_lookup.get(myLookup); // get the value of IMPL_LOOKUP from the Lookup instance and save it in a new Lookup object
// test the trusted Lookup
MethodHandle pmh = lutrusted.findVirtual(NestedTestClass.class, "gimmeTheAnswer", MethodType.methodType(int.class));
System.out.println(pmh.invoke(ntc));
} catch (Throwable e) {
e.printStackTrace();
}
}
// nested class with private method for testing
class NestedTestClass{
#SuppressWarnings("unused")
private int gimmeTheAnswer(){
return 42;
}
}
}
It works with JDK 7, but could break in JDK 8. And be cautious! My antivirus gave an alarm when I executed it.
I think there isn't a public or clean way to do it.
I had a similar issue and finally found a solution: Access non-public (java-native) classes from JDK (7).

Here's a similiar solution which includes arguments in a private
function (I just happened to have the code lying around from a previous project):
class name:
InspectionTree.java
function signature:
private String getSamePackagePathAndName(String className, String classPath)
String firstName = "John";
String lastName = "Smith";
//call the class's constructor to set up the instance, before calling the private function
InspectionTree inspectionTree = new InspectionTree(firstName, lastName);
String privateMethodName ="getSamePackagePathAndName";
Class[] privateMethodArgClasses = new Class[] { String.class, String.class };
Method method =
inspectionTree.getClass().getDeclaredMethod(privateMethodName, privateArgClasses);
method.setAccessible(true);
String className = "Person";
String classPath = "C:\\workspace";
Object[] params = new Object[]{className, classPath};
//note the return type of function 'getSamePackagePathAndName' is a String, so we cast
//the return type here as a string
String answer= (String)method.invoke(inspectionTree, params);
method.setAccessible(false);

Related

What is the purpose of using separate {} block in a function? [duplicate]

Are there any practical uses of anonymous code blocks in Java?
public static void main(String[] args) {
// in
{
// out
}
}
Please note that this is not about named blocks, i.e.
name: {
if ( /* something */ )
break name;
}
.
They restrict variable scope.
public void foo()
{
{
int i = 10;
}
System.out.println(i); // Won't compile.
}
In practice, though, if you find yourself using such a code block that's probably a sign that you want to refactor that block out to a method.
#David Seiler's answer is right, but I would contend that code blocks are very useful and should be used frequently and don't necessarily indicate the need to factor out into a method. I find they are particularly useful for constructing Swing Component trees, e.g:
JPanel mainPanel = new JPanel(new BorderLayout());
{
JLabel centerLabel = new JLabel();
centerLabel.setText("Hello World");
mainPanel.add(centerLabel, BorderLayout.CENTER);
}
{
JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0,0));
{
JLabel label1 = new JLabel();
label1.setText("Hello");
southPanel.add(label1);
}
{
JLabel label2 = new JLabel();
label2.setText("World");
southPanel.add(label2);
}
mainPanel.add(southPanel, BorderLayout.SOUTH);
}
Not only do the code blocks limit the scope of variables as tightly as possible (which is always good, especially when dealing with mutable state and non-final variables), but they also illustrate the component hierarchy much in the way as XML / HTML making the code easier to read, write and maintain.
My issue with factoring out each component instantiation into a method is that
The method will only be used once yet exposed to a wider audience, even if it is a private instance method.
It's harder to read, imagining a deeper more complex component tree, you'd have to drill down to find the code you're interested, and then loose visual context.
In this Swing example, I find that when complexity really does grow beyond manageability it indicates that it's time to factor out a branch of the tree into a new class rather than a bunch of small methods.
It's usually best to make the scope of local variables as small as possible. Anonymous code blocks can help with this.
I find this especially useful with switch statements. Consider the following example, without anonymous code blocks:
public String manipulate(Mode mode) {
switch(mode) {
case FOO:
String result = foo();
tweak(result);
return result;
case BAR:
String result = bar(); // Compiler error
twiddle(result);
return result;
case BAZ:
String rsult = bar(); // Whoops, typo!
twang(result); // No compiler error
return result;
}
}
And with anonymous code blocks:
public String manipulate(Mode mode) {
switch(mode) {
case FOO: {
String result = foo();
tweak(result);
return result;
}
case BAR: {
String result = bar(); // No compiler error
twiddle(result);
return result;
}
case BAZ: {
String rsult = bar(); // Whoops, typo!
twang(result); // Compiler error
return result;
}
}
}
I consider the second version to be cleaner and easier to read. And, it reduces the scope of variables declared within the switch to the case to which they were declared, which in my experience is what you want 99% of the time anyways.
Be warned however, it does not change the behavior for case fall-through - you'll still need to remember to include a break or return to prevent it!
I think you and/or the other answers are confusing two distinct syntactic constructs; namely Instance Initializers and Blocks. (And by the way, a "named block" is really a Labeled Statement, where the Statement happens to be a Block.)
An Instance Initializer is used at the syntactic level of a class member; e.g.
public class Test {
final int foo;
{
// Some complicated initialization sequence; e.g.
int tmp;
if (...) {
...
tmp = ...
} else {
...
tmp = ...
}
foo = tmp;
}
}
The Initializer construct is most commonly used with anonymous classes as per #dfa's example. Another use-case is for doing complicated initialization of 'final' attributes; e.g. see the example above. (However, it is more common to do this using a regular constructor. The pattern above is more commonly used with Static Initializers.)
The other construct is an ordinary block and appears within a code block such as method; e.g.
public void test() {
int i = 1;
{
int j = 2;
...
}
{
int j = 3;
...
}
}
Blocks are most commonly used as part of control statements to group a sequence of statements. But when you use them above, they (just) allow you to restrict the visibility of declarations; e.g. j in the above.
This usually indicates that you need to refactor your code, but it is not always clear cut. For example, you sometimes see this sort of thing in interpreters coded in Java. The statements in the switch arms could be factored into separate methods, but this may result in a significant performance hit for the "inner loop" of an interpreter; e.g.
switch (op) {
case OP1: {
int tmp = ...;
// do something
break;
}
case OP2: {
int tmp = ...;
// do something else
break;
}
...
};
You may use it as constructor for anonymous inner classes.
Like this:
This way you can initialize your object, since the free block is executed during the object construction.
It is not restricted to anonymous inner classes, it applies to regular classes too.
public class SomeClass {
public List data;{
data = new ArrayList();
data.add(1);
data.add(1);
data.add(1);
}
}
Anonymous blocks are useful for limiting the scope of a variable as well as for double brace initialization.
Compare
Set<String> validCodes = new HashSet<String>();
validCodes.add("XZ13s");
validCodes.add("AB21/X");
validCodes.add("YYLEX");
validCodes.add("AR2D");
with
Set<String> validCodes = new HashSet<String>() {{
add("XZ13s");
add("AB21/X");
add("YYLEX");
add("AR5E");
}};
Instance initializer block:
class Test {
// this line of code is executed whenever a new instance of Test is created
{ System.out.println("Instance created!"); }
public static void main() {
new Test(); // prints "Instance created!"
new Test(); // prints "Instance created!"
}
}
Anonymous initializer block:
class Test {
class Main {
public void method() {
System.out.println("Test method");
}
}
public static void main(String[] args) {
new Test().new Main() {
{
method(); // prints "Test method"
}
};
{
//=========================================================================
// which means you can even create a List using double brace
List<String> list = new ArrayList<>() {
{
add("el1");
add("el2");
}
};
System.out.println(list); // prints [el1, el2]
}
{
//==========================================================================
// you can even create your own methods for your anonymous class and use them
List<String> list = new ArrayList<String>() {
private void myCustomMethod(String s1, String s2) {
add(s1);
add(s2);
}
{
myCustomMethod("el3", "el4");
}
};
System.out.println(list); // prints [el3, el4]
}
}
}
Variable scope restrict:
class Test {
public static void main() {
{ int i = 20; }
System.out.println(i); // error
}
}
You can use a block to initialize a final variable from the parent scope. This a nice way to limit the scope of some variables only used to initialize the single variable.
public void test(final int x) {
final ClassA a;
final ClassB b;
{
final ClassC parmC = getC(x);
a = parmC.getA();
b = parmC.getB();
}
//... a and b are initialized
}
In general it's preferable to move the block into a method, but this syntax can be nice for one-off cases when multiple variables need to be returned and you don't want to create a wrapper class.
I use the anonymous blocks for all the reasons explained in other answers, which boils down to limiting the scope of variables. I also use them to have proper delimitation of pairs of method belonging together.
Consider the following excerpt:
jg.writeStartObject();
{
jg.writeStringField("fieldName", ((JsonFormFieldDependencyData.FieldLocator) valueOrLocator).getFieldName());
jg.writeStringField("kind", "field");
}
jg.writeEndObject();
Not only you can see at a glance that the methods are properly paired, but doesn't also kind of look like the output too ?
Just be careful to not abuse it and end up in-lining methods ^^
Refer to
Are fields initialized before constructor code is run in Java?
for the order or execution used in this discussion.
Instance init blocks in Java solve initialization problems other languages have been grappling with - what if we need to enforce of perform an instance initialization that must be run but only after all the static intializers and constructors have completed.
Consider this issue is more prevalent in C# with WPF components where sequence of component initialization is tighter. In Java backend such issues are probably resolved by some redesign. So this remains an overly simplistic illustration of the issue.
public class SessionInfo {
public String uri;
..blah, blah ..
}
abstract public class Session {
final public SessionInfo sessInf;
final public Connection connection;
public Session(SessionInfo sessInf) {
this.sessInf = sessInf;
this.connection = connect(sessInf.uri);
}
abstract void connect(String uri) throws NullPointerException;
}
sessInf.uri is looked up by each impl by the impl constructor.
abstract public class SessionImpl extends Session {
public SessionImpl (SessionInfo sessInf) {
super(sessInf);
sessInf.uri = lookUpUri();
}
..blah, blah ..
}
If you trace the flow, you will find that SessionImpl connect would throw NPE, simply because
SessionImpl constructor is run after constructor of parent Session.
therefore sessInf.uri will be null
and connect(sessInf.uri) at parent constructor would hit NPE.
The solution for such requirement for such a right initialization cycle is
abstract public class Session {
final public SessionInfo sessInf;
final public Connection connection;
public Session(SessionInfo sessInf) {
this.sessInf = sessInf;
}
abstract void connect(String uri) throws NullPointerException;
// This block runs after all the constuctors and static members have completed
{
// instance init blocks can initialize final instance objects.
this.connection = connect(sessInf.uri);
}
}
In this way, you will be able to enforce getting connection onto all extension classes and have it done after all constructors have completed.
Describe a task, either with a comment or inherently due to the structure of your code and the identifiers chosen, and then use code blocks to create a hierarchical relationship there where the language itself doesn't enforce one. For example:
public void sendAdminMessage(String msg) throws IOException {
MessageService service; {
String senderKey = properties.get("admin-message-server");
service = MessageService.of(senderKey);
if (!ms.available()) {
throw new MessageServiceException("Not available: " + senderKey);
}
}
/* workaround for issue 1298: Stop sending passwords. */ {
final Pattern p = Pattern.compile("^(.*?)\"pass\":.*(\"stamp\".*)$");
Matcher m = p.matcher(msg);
if (m.matches()) msg = m.group(1) + m.group(2);
}
...
}
The above is just some sample code to explain the concept. The first block is 'documented' by what is immediately preceding it: That block serves to initialize the service variable. The second block is documented by a comment. In both cases, the block provide 'scope' for the comment/variable declaration: They explain where that particular process ends. It's an alternative to this much more common style:
public void sendAdminMessage(String msg) throws IOException {
// START: initialize service
String senderKey = properties.get("admin-message-server");
MessageService service = MessageService.of(senderKey);
if (!ms.available()) {
throw new MessageServiceException("Not available: " + senderKey);
}
// END: initialize service
// START: workaround for issue 1298: Stop sending passwords.
final Pattern p = Pattern.compile("^(.*?)\"pass\":.*(\"stamp\".*)$");
Matcher m = p.matcher(msg);
if (m.matches()) msg = m.group(1) + m.group(2);
// END: workaround for issue 1298: Stop sending passwords.
...
}
The blocks are better, though: They let you use your editor tooling to navigate more efficiently ('go to end of block'), they scope the local variables used within the block so that they cannot escape, and most of all, they align the concept of containment: You are already familiar, as java programmer, with the concept of containment: for blocks, if blocks, method blocks: They are all expressions of hierarchy in code flow. Containment for code for documentary reasons instead of technical is still containment. Why use a different mechanism? Consistency is useful. Less mental load.
NB: Most likely the best design is to isolate the initialisation of the MessageService object to a separate method. However, this does lead to spaghettification: At some point isolating a simple and easily understood task to a method makes it harder to reason about method structure: By isolating it, you've turned the job of initializing the messageservice into a black box (at least, until you look at the helper method), and to fully read the code in order of how it flows, you need to hop around all over your source files. That's usually the better choice (the alternative is very long methods that are hard to test, or reuse parts of), but there are times when it's not. For example, if your block contains references to a significant number of local variables: If you make a helper method you'd have to pass all those variables. A method is also not control flow and local variable transparent (a helper method cannot break out of the loop from the main method, and a helper method cannot see or modify the local variables from the main method). Sometimes that's an impediment.

How to test private member objects without making a new object

I'm trying to write unit test against a class. I can't change the class, but I think it's possible to test using reflection. I just don't know how to do it. Here's the class:
public class MyClass extends AnotherClass implements TheInterface
{
private enum SomeTypes
{
SAMPLE01, SAMPLE02, SAMPLE03
}
private CircularList<SomeTypes> someTypesList;
Date date= new Date();
private SomeOtherClassProcessor01 someOtherClassProcessor01;
private SomeOtherClassProcessor02 someOtherClassProcessor02;
private SomeOtherClassProcessor03 someOtherClassProcessor03;
public Properties initialize (Properties properties) throws Exception
{
Properties propertiesToReturn = super.initialize(properties);
someTypesList = new CircularList<SomeTypes> (Arrays.asList(SomeTypes.values()));
someOtherClassProcessor01 = new SomeOtherClassProcessor01();
someOtherClassProcessor02 = new SomeOtherClassProcessor02();
someOtherClassProcessor03 = new SomeOtherClassProcessor03();
return propertiesToReturn;
}
#Override
public void get(ImportedClass someParams) throws Exception
{
SomeTypes types = someTypesList.getFirstAndRotate();
switch(types)
{
case SAMPLE01:
someOtherClassProcessor01.doSomething(someParams, date);
break;
case SAMPLE02:
someOtherClassProcessor02.doSomething(someParams, date);
break;
case SAMPLE03:
someOtherClassProcessor03.doSomething(someParams, date);
break;
default:
throw new IllegalArgumentException("This " + types + " was not implemented.");
}
}
}
For my test this is what I have so far... not sure how to actually do it.
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClass.class)
public class TestingMyClass
{
MyClass mockMyClass;
SomeOtherClassProcessor01 someOtherClassProcessor01;
SomeOtherClassProcessor02 someOtherClassProcessor02;
SomeOtherClassProcessor03 someOtherClassProcessor03;
Date date;
#Before
public void initialize () throws Exception
{
mockMyClass = spy(new MyClass());
mockSomeOtherClassProcessor01 = mock(SomeOtherClassProcessor01.class);
mockSomeOtherClassProcessor02 = mock(SomeOtherClassProcessor02.class);
mockSomeOtherClassProcessor03 = mock(SomeOtherClassProcessor03.class);
}
#Test
public void testingGet() throws Exception
{
date = new Date();
//this is where I'm stuck
Whitebox.setInternalState(mockMyClass, "someOtherClassProcessor01", mockSomeOtherClassProcessor01);
}
}
Would it be possible to use whitebox for this? I need to make sure that there's a call inside the getter for those objects. Should I try something like when(someOtherClassProcessor01.doSomething(any(), date)).thenReturn(true)? Please let me know if you need more details.
edit: is even possible to mock private enum SomeTypes?
One option is to substitute your own (mocked) implementations of SomeOtherClassProcessor into MyClass using reflection:
MyClass myClass = new MyClass();
SomeOtherProcessor01 mockProcessor01 = mock(SomeOtherProcessor01.class);
// reflection bit: find the field by its name
// handle NoSuchFieldException
Field someProcessorField = MyClass.getDeclaredField("someOtherProcessor01");
// the field is declared as private, so make it accessible in order to work with it
someProcessorField.setAccessible(true);
// now set your mocked processor into the field.
// First argument is the object to change; second argument - new value for the field
someProcessorField.set(myClass, mockProcessor01);
PS. Using PowerMock and/or reflection is surrender to bad design (as per Timothy :). You should not be depending on code you that isn't already well-tested, and if it is, you shouldn't try to test it again. Suppose your testing actually reveals a bug - how would you fix it if you don't control the code? Suppose Java 11 becomes a thing and prohibits your use of reflection. Suppose the code you're testing changes and the fields get renamed - with reflection, you don't have compile-time safety... List of potential issues goes on

How to flexibly select a single method or class from a long list of sequentially named methods or classes

I know the simple way is to use a switch statement, but that is not what I am asking. I want to know, if I can call a method, based on its name as a String that I can modify from the user's input.
For example, I have a bunch of methods named:
func01
func02
func03
...
I want to call them using a string "func", which I modify by adding a numerical suffix to it, like 01, 02 or 03. I want call them using a few lines of code that will work for any number of methods.
Solution with Reflection
You could use Reflection to call the methods.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Main {
public static void main(String args[]) throws Exception {
// Just an example calling all the methods
for (int i = 1; i < 100; i++) {
Object object = invokeMethod("func", i);
if (object != null) {
// Do something with object, cast it, etc. ...
} else {
// Error calling the methods
}
}
}
private static Object invokeMethod(String methodBaseName, int number) {
// Number format will be two digits padded by zeros,
// e.g. 01, 02, ..., 18, ...
// For three digits use "%03d" and so on or calculate
// the digits from the number itself
String methodName = methodBaseName + String.format("%02d", number);
try {
Method methodToInvoke = MethodClass.class.getMethod(methodName);
return methodToInvoke.invoke(new MethodClass());
} catch (NoSuchMethodException | SecurityException
| IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
// Alternatively handle this errors
return null;
}
}
}
class MethodClass {
public Object func01() {
// ...
}
// ...
public Object func99() {
// ...
}
}
Alternatively for static methods, just use:
Method method = MethodClass.class.getMethod(...);
method.invoke(MethodClass.class);
If you want to add parameters, modify the code like this:
getMethod(methodName, parameterType1.class, parameterType2.class, ...);
invoke(..., parameter1, parameter2, ...);
If you want to use a return value, just change the return type from Object to the concrete type and cast the return value from invoke to this type, e.g. Integer:
Integer result = (Integer) method.invoke(...);
Important notice
What you are trying to do is very dangerous. Reflection can be a critical harm for the security of your application. You should never allow a user to input a method name to invoke a method, otherwise he or she could potentially call any method to gain control of your application or memory. Beware of this.
You can do it using reflection. If your method is static, use the code like this:
Method method = ClassName.class.getMethod(name, param1.getClass(), param2.getClass(), ..);
method.invoke(ClassName.class, param1, param2, ..);
Or if your method isn't static, use the code like this:
Method method = object.getClass().getMethod(name, param1.getClass(), param2.getClass(), ..);
method.invoke(object, param1, param2, ..);
Reflection is a dangerous and almost impossible feature to use correctly for new Java programmers. Obtaining a method or other object-oriented element via a string is an antipattern; it breaks type safety, is very difficult to maintain and debug, and will cause you endless bugs. I speak from experience.
Instead, use a single method with overrides for each type of action you want, and let object orientation help you. If you really need a string to tell you which logic flow to use, perhaps an enum will rescue you. You can use the valueOf() method to parse the string into a valid enum, then call the desired functionality through each enum constant's implementation of an abstract method in the enum.
public class Processor
{
FOLD
{
#Override
public void process()
{
// fold logic
}
},
SPINDLE
{
#Override
public void process()
{
// spindle logic
}
},
MUTILATE
{
#Override
public void process()
{
// mutilate logic
}
},
;
abstract public void process();
}
Your client code will be similar to
Processor.valueOf(text).process();
with suitable error checking and exception handling, of course.

Java Syntax: Code block after semicolon? [duplicate]

Are there any practical uses of anonymous code blocks in Java?
public static void main(String[] args) {
// in
{
// out
}
}
Please note that this is not about named blocks, i.e.
name: {
if ( /* something */ )
break name;
}
.
They restrict variable scope.
public void foo()
{
{
int i = 10;
}
System.out.println(i); // Won't compile.
}
In practice, though, if you find yourself using such a code block that's probably a sign that you want to refactor that block out to a method.
#David Seiler's answer is right, but I would contend that code blocks are very useful and should be used frequently and don't necessarily indicate the need to factor out into a method. I find they are particularly useful for constructing Swing Component trees, e.g:
JPanel mainPanel = new JPanel(new BorderLayout());
{
JLabel centerLabel = new JLabel();
centerLabel.setText("Hello World");
mainPanel.add(centerLabel, BorderLayout.CENTER);
}
{
JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0,0));
{
JLabel label1 = new JLabel();
label1.setText("Hello");
southPanel.add(label1);
}
{
JLabel label2 = new JLabel();
label2.setText("World");
southPanel.add(label2);
}
mainPanel.add(southPanel, BorderLayout.SOUTH);
}
Not only do the code blocks limit the scope of variables as tightly as possible (which is always good, especially when dealing with mutable state and non-final variables), but they also illustrate the component hierarchy much in the way as XML / HTML making the code easier to read, write and maintain.
My issue with factoring out each component instantiation into a method is that
The method will only be used once yet exposed to a wider audience, even if it is a private instance method.
It's harder to read, imagining a deeper more complex component tree, you'd have to drill down to find the code you're interested, and then loose visual context.
In this Swing example, I find that when complexity really does grow beyond manageability it indicates that it's time to factor out a branch of the tree into a new class rather than a bunch of small methods.
It's usually best to make the scope of local variables as small as possible. Anonymous code blocks can help with this.
I find this especially useful with switch statements. Consider the following example, without anonymous code blocks:
public String manipulate(Mode mode) {
switch(mode) {
case FOO:
String result = foo();
tweak(result);
return result;
case BAR:
String result = bar(); // Compiler error
twiddle(result);
return result;
case BAZ:
String rsult = bar(); // Whoops, typo!
twang(result); // No compiler error
return result;
}
}
And with anonymous code blocks:
public String manipulate(Mode mode) {
switch(mode) {
case FOO: {
String result = foo();
tweak(result);
return result;
}
case BAR: {
String result = bar(); // No compiler error
twiddle(result);
return result;
}
case BAZ: {
String rsult = bar(); // Whoops, typo!
twang(result); // Compiler error
return result;
}
}
}
I consider the second version to be cleaner and easier to read. And, it reduces the scope of variables declared within the switch to the case to which they were declared, which in my experience is what you want 99% of the time anyways.
Be warned however, it does not change the behavior for case fall-through - you'll still need to remember to include a break or return to prevent it!
I think you and/or the other answers are confusing two distinct syntactic constructs; namely Instance Initializers and Blocks. (And by the way, a "named block" is really a Labeled Statement, where the Statement happens to be a Block.)
An Instance Initializer is used at the syntactic level of a class member; e.g.
public class Test {
final int foo;
{
// Some complicated initialization sequence; e.g.
int tmp;
if (...) {
...
tmp = ...
} else {
...
tmp = ...
}
foo = tmp;
}
}
The Initializer construct is most commonly used with anonymous classes as per #dfa's example. Another use-case is for doing complicated initialization of 'final' attributes; e.g. see the example above. (However, it is more common to do this using a regular constructor. The pattern above is more commonly used with Static Initializers.)
The other construct is an ordinary block and appears within a code block such as method; e.g.
public void test() {
int i = 1;
{
int j = 2;
...
}
{
int j = 3;
...
}
}
Blocks are most commonly used as part of control statements to group a sequence of statements. But when you use them above, they (just) allow you to restrict the visibility of declarations; e.g. j in the above.
This usually indicates that you need to refactor your code, but it is not always clear cut. For example, you sometimes see this sort of thing in interpreters coded in Java. The statements in the switch arms could be factored into separate methods, but this may result in a significant performance hit for the "inner loop" of an interpreter; e.g.
switch (op) {
case OP1: {
int tmp = ...;
// do something
break;
}
case OP2: {
int tmp = ...;
// do something else
break;
}
...
};
You may use it as constructor for anonymous inner classes.
Like this:
This way you can initialize your object, since the free block is executed during the object construction.
It is not restricted to anonymous inner classes, it applies to regular classes too.
public class SomeClass {
public List data;{
data = new ArrayList();
data.add(1);
data.add(1);
data.add(1);
}
}
Anonymous blocks are useful for limiting the scope of a variable as well as for double brace initialization.
Compare
Set<String> validCodes = new HashSet<String>();
validCodes.add("XZ13s");
validCodes.add("AB21/X");
validCodes.add("YYLEX");
validCodes.add("AR2D");
with
Set<String> validCodes = new HashSet<String>() {{
add("XZ13s");
add("AB21/X");
add("YYLEX");
add("AR5E");
}};
Instance initializer block:
class Test {
// this line of code is executed whenever a new instance of Test is created
{ System.out.println("Instance created!"); }
public static void main() {
new Test(); // prints "Instance created!"
new Test(); // prints "Instance created!"
}
}
Anonymous initializer block:
class Test {
class Main {
public void method() {
System.out.println("Test method");
}
}
public static void main(String[] args) {
new Test().new Main() {
{
method(); // prints "Test method"
}
};
{
//=========================================================================
// which means you can even create a List using double brace
List<String> list = new ArrayList<>() {
{
add("el1");
add("el2");
}
};
System.out.println(list); // prints [el1, el2]
}
{
//==========================================================================
// you can even create your own methods for your anonymous class and use them
List<String> list = new ArrayList<String>() {
private void myCustomMethod(String s1, String s2) {
add(s1);
add(s2);
}
{
myCustomMethod("el3", "el4");
}
};
System.out.println(list); // prints [el3, el4]
}
}
}
Variable scope restrict:
class Test {
public static void main() {
{ int i = 20; }
System.out.println(i); // error
}
}
You can use a block to initialize a final variable from the parent scope. This a nice way to limit the scope of some variables only used to initialize the single variable.
public void test(final int x) {
final ClassA a;
final ClassB b;
{
final ClassC parmC = getC(x);
a = parmC.getA();
b = parmC.getB();
}
//... a and b are initialized
}
In general it's preferable to move the block into a method, but this syntax can be nice for one-off cases when multiple variables need to be returned and you don't want to create a wrapper class.
I use the anonymous blocks for all the reasons explained in other answers, which boils down to limiting the scope of variables. I also use them to have proper delimitation of pairs of method belonging together.
Consider the following excerpt:
jg.writeStartObject();
{
jg.writeStringField("fieldName", ((JsonFormFieldDependencyData.FieldLocator) valueOrLocator).getFieldName());
jg.writeStringField("kind", "field");
}
jg.writeEndObject();
Not only you can see at a glance that the methods are properly paired, but doesn't also kind of look like the output too ?
Just be careful to not abuse it and end up in-lining methods ^^
Refer to
Are fields initialized before constructor code is run in Java?
for the order or execution used in this discussion.
Instance init blocks in Java solve initialization problems other languages have been grappling with - what if we need to enforce of perform an instance initialization that must be run but only after all the static intializers and constructors have completed.
Consider this issue is more prevalent in C# with WPF components where sequence of component initialization is tighter. In Java backend such issues are probably resolved by some redesign. So this remains an overly simplistic illustration of the issue.
public class SessionInfo {
public String uri;
..blah, blah ..
}
abstract public class Session {
final public SessionInfo sessInf;
final public Connection connection;
public Session(SessionInfo sessInf) {
this.sessInf = sessInf;
this.connection = connect(sessInf.uri);
}
abstract void connect(String uri) throws NullPointerException;
}
sessInf.uri is looked up by each impl by the impl constructor.
abstract public class SessionImpl extends Session {
public SessionImpl (SessionInfo sessInf) {
super(sessInf);
sessInf.uri = lookUpUri();
}
..blah, blah ..
}
If you trace the flow, you will find that SessionImpl connect would throw NPE, simply because
SessionImpl constructor is run after constructor of parent Session.
therefore sessInf.uri will be null
and connect(sessInf.uri) at parent constructor would hit NPE.
The solution for such requirement for such a right initialization cycle is
abstract public class Session {
final public SessionInfo sessInf;
final public Connection connection;
public Session(SessionInfo sessInf) {
this.sessInf = sessInf;
}
abstract void connect(String uri) throws NullPointerException;
// This block runs after all the constuctors and static members have completed
{
// instance init blocks can initialize final instance objects.
this.connection = connect(sessInf.uri);
}
}
In this way, you will be able to enforce getting connection onto all extension classes and have it done after all constructors have completed.
Describe a task, either with a comment or inherently due to the structure of your code and the identifiers chosen, and then use code blocks to create a hierarchical relationship there where the language itself doesn't enforce one. For example:
public void sendAdminMessage(String msg) throws IOException {
MessageService service; {
String senderKey = properties.get("admin-message-server");
service = MessageService.of(senderKey);
if (!ms.available()) {
throw new MessageServiceException("Not available: " + senderKey);
}
}
/* workaround for issue 1298: Stop sending passwords. */ {
final Pattern p = Pattern.compile("^(.*?)\"pass\":.*(\"stamp\".*)$");
Matcher m = p.matcher(msg);
if (m.matches()) msg = m.group(1) + m.group(2);
}
...
}
The above is just some sample code to explain the concept. The first block is 'documented' by what is immediately preceding it: That block serves to initialize the service variable. The second block is documented by a comment. In both cases, the block provide 'scope' for the comment/variable declaration: They explain where that particular process ends. It's an alternative to this much more common style:
public void sendAdminMessage(String msg) throws IOException {
// START: initialize service
String senderKey = properties.get("admin-message-server");
MessageService service = MessageService.of(senderKey);
if (!ms.available()) {
throw new MessageServiceException("Not available: " + senderKey);
}
// END: initialize service
// START: workaround for issue 1298: Stop sending passwords.
final Pattern p = Pattern.compile("^(.*?)\"pass\":.*(\"stamp\".*)$");
Matcher m = p.matcher(msg);
if (m.matches()) msg = m.group(1) + m.group(2);
// END: workaround for issue 1298: Stop sending passwords.
...
}
The blocks are better, though: They let you use your editor tooling to navigate more efficiently ('go to end of block'), they scope the local variables used within the block so that they cannot escape, and most of all, they align the concept of containment: You are already familiar, as java programmer, with the concept of containment: for blocks, if blocks, method blocks: They are all expressions of hierarchy in code flow. Containment for code for documentary reasons instead of technical is still containment. Why use a different mechanism? Consistency is useful. Less mental load.
NB: Most likely the best design is to isolate the initialisation of the MessageService object to a separate method. However, this does lead to spaghettification: At some point isolating a simple and easily understood task to a method makes it harder to reason about method structure: By isolating it, you've turned the job of initializing the messageservice into a black box (at least, until you look at the helper method), and to fully read the code in order of how it flows, you need to hop around all over your source files. That's usually the better choice (the alternative is very long methods that are hard to test, or reuse parts of), but there are times when it's not. For example, if your block contains references to a significant number of local variables: If you make a helper method you'd have to pass all those variables. A method is also not control flow and local variable transparent (a helper method cannot break out of the loop from the main method, and a helper method cannot see or modify the local variables from the main method). Sometimes that's an impediment.

Java - Get object of class depending on its name

this is my situation:
I have a method which has a String as parameter. This method has to receive an object from a class called Urls. The object it has to recieve, has the same name as the value of the String. Here is my code:
private Object getObject(String objectName){
try
{
Field field = Urls.class.getField(objectName);
}
catch (NoSuchFieldException e)
{}
catch (IllegalAccessException e)
{}
}
And here is my Urls class:
public class Urls{
public static final String[] ASTUN = new String[]{
"http://www.astun.com/camara/truchas.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=astun/astun.jpg",
"http://www.astun.com/camara/caba%C3%B1a%20sarrios.jpg",
"http://www.astun.com/camara/sector%20sarrios.jpg",
"http://www.astun.com/camara/sector%20raca%20prad.jpg",
"http://www.astun.com/camara/sector%20aguila%20cr.jpg",
"http://www.astun.com/camara/sector%20truchas.jpg",
"http://www.astun.com/camara/sector%20llanos%20.jpg",
"http://www.astun.com/camara/llegada.jpg",
"http://www.astun.com/camara/terraza.jpg",
"http://www.astun.com/camara/panoramica.jpg",
"http://www.astun.com/camara/snow.jpg"
};
private static final String[] CANDANCHU = new String[]{
"https://www.todonieve.com/photowebcam.asp?fotografia=candanchu/candanchu.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=CandanchuNew/CandanchuNew.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=candanchu_rinconada/candanchu_rinco.jpg",
"https://www.todonieve.com/photowebcam.asp?fotografia=candanchu_tobazo/candanchu_tobazo.jpg"
};
}
So, that way I have a Field object, but how can I get the String[] of that field? I have read about the get(Object object) method of Field class but it seems that i doesnt do what I want to do...
EDIT: I WANT TO GET ASTUN OR CANDACHU STRING ARRAYS
Avoid reflection whenever possible. It often does more harm than good.
Put them into a map:
public class Urls {
//put your arrays here
private static final Map<String,String[]> urlsLists = new HashMap<>();
static {
urlLists.put("ASTUN", ASTUN);
urlLists.put("CANDANCHU", CANDANCHU);
}
public static String[] getUrlList(String name) {
return urlLists.get(name);
}
}
And then call it like this:
private Object getObject(String objectName){
return Urls.getUrlList(objectName);
}
Update
You loose a lot of nice stuff Java help you with, including type-safety, encapsulation and compile-time checks. Because of this it is a lot more error prone. There is a much increased risk of run-time errors and you need a bunch of extra code to handle this. Your brief example already have two catch clauses. Trust me - that will just get worse.
You can even improve type-safety more by creating an Enum to define url-types. Then you will get compile time checks that you have spelled the name right and even auto-completion all through-out your code. :)
public class Urls {
public enum UrlTypes {ASTUN; CANDANCHU;}
// ..
private static final Map<UrlTypes,String[]> urlsLists = new HashMap<>();
static {
urlLists.put(UrlTypes.ASTUN, ASTUN);
urlLists.put(UrlTypes.CANDANCHU, CANDANCHU);
}
..
public static String[] getUrlList(UrlTypes name) {
return urlLists.get(name);
}
}
Every error you can catch at compile-time instead of at run-time can save you between half an hour or half a week of work, when things get complex.
You will need something like this:
private Object getObject(String objectName){
try
{
Field field = Urls.class.getField(objectName);
Object o = field.get(null); // null works as well.
return o;
}
catch (NoSuchFieldException e)
{ e.printStackTrace(); }
catch (IllegalAccessException e)
{ e.printStackTrace(); }
}
private String[] getStringArray(String arrayName)
{
return (String[]) getObject(arrayName);
}
Usage:
Object o = getObject("ASTUN");
// or:
String[] arr = getStringArray("ASTUN");
getField will return the (reflexive) representation of the field concept in the Urls class. You then need to bind it with an actual object of that class to have access to the contents of the field in that object.
Field field = Urls.class.getFiled(objectName);
String[] values = (String[]) field.get(o);
where o is a variable of type Urls.
Note the cast to String[] as Field.get() will return an Object as it does not know the actual type. You should make sure that the type is indeed correct by using the Field.getType() method and compare that to Urls.class.
Since objects dont have names, you will need to create ypur own class, put the field variable in there, then use that instead of Object. Or use a Map for better key/value logging.

Categories