Calling Outer Class Function from Inner Class

Calling outer class function from inner class

You need to prefix the call by the outer class:

Outer.this.show();

Access outer class function from Object of Inner Class

Short answer: the reference to Outer.this is private in Inner so you cannot access the reference to the Outer instance from an instance of the Inner.

You can export this reference thus:

class Outer {
Outer() {
}

class Inner {
Inner() {
}

public Outer getOuter() {
return Outer.this;
}
}

void func() {
System.out.println("Outer");
}
}

Then you can simply do:

ii.getOuter().func();

How to call outer class' super method from inner class in Kotlin?

Use the super@OuterClass.method() syntax:

open class C {
open fun f() { println("C.f()") }
}

class D : C() {
override fun f() { println("D.f()") }

inner class X {
fun g() {
super@D.f() // <- here
}
}
}

This is similar to how Java OuterClass.this is expressed in Kotlin as this@OuterClass.

How to access outer class from an inner class?

The methods of a nested class cannot directly access the instance attributes of the outer class.

Note that it is not necessarily the case that an instance of the outer class exists even when you have created an instance of the inner class.

In fact, it is often recommended against using nested classes, since the nesting does not imply any particular relationship between the inner and outer classes.

inner class access to outer class method, same method names

01 public class A{
02 void test(){};
03 public class B{
04 void test(){
05 test(); // local B.test() method, so recursion, use A.this.test();
06 }
07 }
08 }

EDIT : As @Thilo mentioned : Avoid using same method names in outer class and inner class, this will avoid naming conflicts.

Java multithreading inner class calling outer class

Not thread-safe

No, manipulating a non-thread-safe List from across threads is not thread-safe.

Synchronized

You could make your handleInput method synchronized as commented by Bodewes. Of course, that method becomes a potential bottleneck, as only one thread at a time can be calling a synchronized method. Perhaps not an issue in your case, but be aware.

Thread-safe collection

Another option is to replace your LinkedList with a thread-safe collection. For example, CopyOnWriteArrayList, CopyOnWriteArraySet, or ConcurrentSkipListSet.

Callable & Future

But I suggest you not mingle your multi-threaded production of Entity objects with collecting and processing those objects. Each task assigned to a background thread should “mind its own business” as much as possible. Having the tasks share a list is entangling them across threads needlessly; that kind of entangling (shared resources) should be avoided wherever possible.

Change your task from being a Runnable to be a Callable so as to return a value. That return value will be each Entity produced.

As you submit each Callable to the executor service, you get back a Future object. Collect those objects. Through each of those objects you can access the result of each task’s work.

Wait for the executor service to finish all submitted tasks. Then inspect the results of each Future.

By using Future objects to collect the results produced by the background threads, and only processing those results after they are all done, we have eliminated the need to make your results collection thread-safe. The original thread collects those results into a list, rather than each thread adding to the list.

Notice how in this example code below we have no resources shared across the tasks running in background threads. Each task does its own thing, reporting its own result via its particular Future object. The tasks no longer access a shared List.

By the way, notice that this example code does not keep the executor service in a member field as does the code in the Question. In our situation here, an executor service should be (1) instantiated, (2) utilized, and (3) shut down all in one action. You must shut down your executor service when no longer needed (or when your app exits). Otherwise its backing thread pool may run indefinitely, like a zombie ‍♂️.

Example code

package work.basil.threading;

import java.net.URI;
import java.net.URISyntaxException;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.*;

public class Status
{
record Entity( UUID uuid , Instant instant ) { }

public List < String > process ()
{
ExecutorService executorService = Executors.newFixedThreadPool( 5 );

List < WebCallTask > tasks = List.of();
try
{
tasks = List.of(
new WebCallTask( new URI( "http://www.Google.com/" ) ) ,
new WebCallTask( new URI( "http://www.DuckDuckGo.com/" ) ) ,
new WebCallTask( new URI( "http://www.Adoptium.net/" ) )
);
} catch ( URISyntaxException e )
{
e.printStackTrace();
}

List < Future < Entity > > futures = List.of();
try { futures = executorService.invokeAll( tasks ); } catch ( InterruptedException e ) { e.printStackTrace(); }

executorService.shutdown();
try { executorService.awaitTermination( 2 , TimeUnit.MINUTES ); } catch ( InterruptedException e ) { e.printStackTrace(); }

List < String > results = new ArrayList <>( tasks.size() );
for ( Future < Entity > future : futures )
{
try
{
Entity entity = future.get();
String result = this.handleInput( entity );
results.add( result );
} catch ( InterruptedException e )
{
e.printStackTrace();
} catch ( ExecutionException e )
{
e.printStackTrace();
}
}
return results;
}

public String handleInput ( Entity entity )
{
if ( Objects.isNull( entity ) ) return "Not Available.";
return entity.toString();
}

private class WebCallTask implements Callable < Entity >
{
private URI uri;

public WebCallTask ( URI uri )
{
this.uri = uri;
}

@Override
public Entity call ()
{
Entity entity = null;
try
{
// Perform some http calls.
// response = httpClient.execute(httpPost);
// Pretend to wait on network call by sleeping.
System.out.println( "Thread: " + Thread.currentThread().getId() + " is sleeping, to pretend doing network call. " + Instant.now() );
try { Thread.sleep( Duration.ofSeconds( ThreadLocalRandom.current().nextInt( 3 , 11 ) ).toMillis() ); } catch ( InterruptedException e ) { e.printStackTrace(); }
entity = new Entity( UUID.randomUUID() , Instant.now() );
System.out.println( "Thread: " + Thread.currentThread().getId() + " produced an `Entity` object. Task done. " + Instant.now() );
} catch ( Exception e ) // In your real code, you would be catching networking errors related to your networkcall.
{
e.printStackTrace();
} finally
{
return entity; // May return `null` as a legitimate value. In real work I would use `Optional< Entity >` here to signal that `null` is a possible and legitimate value. But let's not overcomplicate this example code.
}
}
}

public static void main ( String[] args )
{
System.out.println( "Thread: " + Thread.currentThread().getId() + " is starting demo. " + Instant.now() );

Status statusApp = new Status();
List < String > output = statusApp.process();
System.out.println( "output = " + output );

System.out.println( "Thread: " + Thread.currentThread().getId() + " is ending demo. " + Instant.now() );
}

}

When run.

Thread: 1 is starting demo. 2021-10-09T03:58:41.269177Z
Thread: 15 is sleeping, to pretend doing network call. 2021-10-09T03:58:41.286424Z
Thread: 16 is sleeping, to pretend doing network call. 2021-10-09T03:58:41.286828Z
Thread: 17 is sleeping, to pretend doing network call. 2021-10-09T03:58:41.288108Z
Thread: 16 produced an `Entity` object. Task done. 2021-10-09T03:58:44.323703Z
Thread: 15 produced an `Entity` object. Task done. 2021-10-09T03:58:46.294364Z
Thread: 17 produced an `Entity` object. Task done. 2021-10-09T03:58:46.294269Z
output = [Entity[uuid=04d73a52-79ec-4a61-becb-ce056d3aa9fa, instant=2021-10-09T03:58:46.294359Z], Entity[uuid=cc5a7266-4101-41bb-b806-8b29b77a82d0, instant=2021-10-09T03:58:44.323688Z], Entity[uuid=3cc24ad9-3ea1-4a24-98d0-c3df4bf161b6, instant=2021-10-09T03:58:46.294254Z]]
Thread: 1 is ending demo. 2021-10-09T03:58:46.321313Z

Way to call inner class by outer class

As you are instantiating Inner within the scope of Outer (inside an instance method), you do not need to explicitly instantiate referencing the Outer clas, like in your example:

Outer.Inner in = new Outer().new Inner();

It is fine to instantiate by just referencing Inner:

 Inner in = new Inner();

This applies to all instance methods within a class, as long as they are not static.

How to access outer class member from an inner class in Python?

The problem with your code is that you didn't understand correctly the meaning of name mangling, that's exactly what you're doing when adding the double leading score in your variable name.

When setting up the variable as self.__x, what you're actually doing is telling the world outside your class that it can only be accessed this way when operating inside the Outer class. If you try to access outside, lets say add after the definition of obj the following print(obj.__x), you'll see the same problem.

The name mangling means that when accessing the variable outside of the scope of your class, you should call the variable _ClassName__variableName, so, in our example, you should use print(obj._Outer__x) to be able to print the variable.

Since your Inner class works the same way, as an outside scope, the simplest solution would be to rewrite your display method this way:

def display(self):
print("str_in : ", self.__str_in)
print("Inside display() of Inner Class")
print("x : ", self.outer._Outer__x)
print("str : ", self.outer._Outer__str)
self.outer.fn()

Now, other thing I noticed, and can generate problems if you didn't do this consciously, is the call self.i1 = self.Inner(Outer()). Here you're not using the same object data that you instantiated as obj, but creating a new instance of Outer and sending this to Inner.

And what's the problem with this?
Let's say you added the following lines:

obj = Outer()
obj._Outer__x = 10
obj.show()

Then the output of your show() will always be x: 20, because this change you've done in the variable, was made to an instance that was not passed to Inner.

If it's not the behaviour you were aiming for, just change this line to:

self.i1 = self.Inner(self)

So now you're effectively passing the instantiated object to Inner

Can outer classes call methods of its inner class?

Create an instance like this and access what you want:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

how to call outer class function from inner function in Javascript?

It's a matter of scope. When you get to functionWeCall(), this starts referring to that very function instead of to the class, thus outFunction() doesn't exist on this. A typical workaround might look like this:

class Outer {
private outFunction() {
console.log("Okay!");
}

public functionWeCall() {
let _this = this;

function innerFunction() {
_this.outFunction();
}
}
}

... but I'd rather advice reworking the whole thing so that you don't have nested functions like that.

Edit: as suggested by @Aluan Haddad, here's the same thing, but with an arrow function:

class Outer {
private outFunction() {
console.log("Okay!");
}

public functionWeCall() {
() => {
this.outFunction();
}
}
}

... and if you want the inner function to still be callable, assign it to a variable:

class Outer {
private outFunction() {
console.log("Okay!");
}

public functionWeCall() {
let innerFunction = () => {
this.outFunction();
}

innerFunction(); // this could be anywhere in the scope of functionWeCall()
}
}


Related Topics



Leave a reply



Submit