Passing an Anonymous Class

I pass the interface as an anonymous implementation to another object like this:

public interface Interface { public int convert (int a); } public static void main(String[] args) throws IOException, InterruptedException { final int[] array = {1,6,3,5,7,8,4,0,3}; Interface inter = new Interface() { public int convert(int a) { int result = a; for (int i = 0; i < array.length; i++) { a=a+array[i]; } return a; } }; SomeObject ty = new SomeObject (); ty.Test(7, inter); } public class SomeObject { public void Test(int number, Interface inter) { System.out.println(inter.convert(number)); } } 

My question is: how does it work? How SomeObject knows an array that is not passed directly to the object (the array is not a member of an anonymous class).

Update
(sorry for the latest update)

what about member methods or method methods that are used in an anonymous class? they are not final

  Interface inter = new Interface() { public int convert(int a) { int result = a + someMemberVar; for (int i = 0; i < array.length; i++) { a=a+array[i]; } return a; } }; 
+6
source share
6 answers

My question is, how does it work? How SomeObject knows about an array that is not passed directly to the object (the array is not a member of the anonymous class).

  • Answer: This is not so; unless you declare the array final.
  • Reasoning: This works (if the array is final), because since it is final, it can be considered as a constant, since the anonymous function knows that the array cannot be modified.

what about member methods or method methods that are used in an anonymous class? they are not final

  • The answer . Instance instances and methods (as well as static variables and methods) are in any case scope when an anonymous class is created.
+2
source

Since the local variable of the method is declared directly inside the method block, it is visible only inside the method, starting with the next statement after the declaration. By the -local method, I mean a variable that is declared inside the method, but outside of any other blocks (for example, while { /* not here */ } ) that can appear inside this method.

And if you see, your anonymous class is also defined as a local class inside the same method after the array declaration. That is why it is visible to the class.

The reason you need to make array final in order to use it inside an anonymous class is because local variables live only until the method lives on, but the object of the local class can live longer (even after the method is done).

+2
source

This is part of the Java visibility and visibility rules. In your current example, this is called Closure . Basically, everything that is defined in a block is visible inside this block. For example, this is valid Java code (anywhere in the method):

 { final int i = 5; // do somthing with i } // cant refernce i here { final int i = 6; // do somthing with i } // cant refernce i here 

Since you are defining a new class inside a block (I would not work if you just initiated it), it sees everything that was declared in one block. The only limit to Java that it refers to is that you cannot change the value after the first assignment in order to avoid problems when the link "escapes" its block (multithreading, lives longer than the declaration block, etc.). If you declare the parameters of the final method, you can also use them because they are defined in one block.

So, if you changed the code to this

  { final int[] array = {1,6,3,5,7,8,4,0,3}; } Object inter = new Object() { public void test() { System.out.println(array); } }; 

This will not work (try).

+1
source

You pass an Interface object that has access to the array to the SomeObject method.

So, SomeObject uses the same Interface object that you passed in the main.

Since the interface has access to the array, it can be used.

This is not SomeObject that uses an array. This is an interface object.

0
source

Java stores a reference to all (final) objects of the surrounding class used in the inner class. If you want to know how this trick is a maid, add the following line to the test method:

 System.out.println(inter.getClass().getDeclaredConstructors()[0].getParameterTypes()[0].getCanonicalName() 

And your output will be "int []"

So, a simple compiler creates a constructor for the inner class and passes it the fields it needs.

0
source

The compiler treats the final variable as a constant and substitutes the value of the corresponding variable in an anonymous class at compile time. The following thread provides excellent details:
You cannot reference a non-finite variable inside an inner class defined in another way

0
source

Source: https://habr.com/ru/post/904162/


All Articles