abstract class as shared memory on different threads - java

I have an abstract class which is inherited by classes that run on different threads. do the variables in this abstract class act as shared memory?
public abstract class A
{
public abstract void foo();
public boolean bar(){
{
List<String> x=new ArrayList();
x.add("a");
//some code
}
}
public class B extends A
{
#Override
public void foo()
{
//some code
}
}
public class C extends A
{
#Override
public void foo()
{
//some code
}
#Override
public boolean bar()
{
List<String> x=new ArrayList();
x.add("a");
//some code
}
}
public class D extends A
{
#Override
public void foo()
{
//some code
}
}
classes B, C and D run in different threads. however x is behaving like a shared memory for A and B and D. is it the expected behaviour? if yes how can i make it thread specific without overriding?

the x variable is not being shared. It's replicated on any thread that invokes the bar() method. If its content is always the same, you should declare it as static final member variable. That is:
public abstract class A
{
static final List<String> x=new ArrayList();
Probably it'd also be a good idea to initialize it through a static initializer: Static initializer in Java

Related

How to avoid creating object only referenced by inner class in Java?

I'm trying to create some system with inner class. My code can be summarized to something like this.
public abstract class A {
public abstract void doSomething();
}
public class B {
public final ArrayList<A> list=new ArrayList<A>();
public B(){
}
}
public class C {
private int i;
public C(B b){
b.list.add(new A(){
public void doSomething(){
i++;
}
});
b.list.add(new A(){
public void doSomething(){
System.out.println(i);
}
});
}
}
public static void main (String[] arg) {
B manager=new B();
new C(manager);
new C(manager);
new C(manager);
}
A is abstract class that will be inherited as inner class (in my original code it is listener class), B is some kind of manager class that hold list of As, and C hold data it's data should be only modified or read by it's inner class and upon initialization it add A to the class B. Code itself works fine. But problem is as there will be various kinds of C something like C2, C3 that does different thing and this leads to my code overwhelmed with thousands of unassigned object new C(manager); this make debugging extra hard and code looks really ugly. So it seems to me my approach in the first place was wrong but have no idea how to avoid this. So how should I change my approach to not have thousands of unassigned objects?
My suggestion is: try not to use constructors to do operations that depend on state (i). Use static functions, and save the state in a separate class (we call it a “context”).
import java.util.ArrayList;
public class Demo {
// A
abstract static class InnerListener {
public abstract void onEvent();
}
// B
static class ListenerManager {
public final ArrayList<InnerListener> listeners = new ArrayList<InnerListener>();
}
static class SideEffectContext {
public int i = 0;
}
// C
static class ListenerUtil {
public static void setupListeners(ListenerManager manager, SideEffectContext context) {
manager.listeners.add(new InnerListener() {
public void onEvent() {
context.i++;
}
});
manager.listeners.add(new InnerListener() {
public void onEvent() {
System.out.println(context.i);
}
});
}
}
public static void main(String[] arg) {
var manager = new ListenerManager();
var ctxA = new SideEffectContext();
var ctxShared = new SideEffectContext();
ListenerUtil.setupListeners(manager, ctxA);
ListenerUtil.setupListeners(manager, ctxShared);
ListenerUtil.setupListeners(manager, ctxShared);
}
}

How to properly use a parameter of type class?

In java, I'd like to do something like this
public class Tata{
public static void f(){
//something
}
public static void g(){
//something
}
}
public class Titi{
public static void f(){
//something
}
public static void g(){
//something
}
}
public class Toto{
private Class c = Tata.class; //or Titi.class
public static void main(String[] args) {
c.f();
c.g();
}
}
To be precise, I'd like to be able to freely switch between classes Tata and Titi, to use their respective methods f or g.
This doesn't work as intended, as I get the cannot resolve method 'f()' error. Simply replacing c.f(); and c.g(); with Tata.f(); and Tata.g(); works fine, but defeats the purpose of using a parameter. How to solve this?
Will turn the comment into answer after all.. The correct (Java) way to deal with what you want is the use of interface. So in your demo code the implementation would be the following:
public interface TheFGFunctions {
void f();
void g();
}
public class Tata implements TheFGFunctions {
#Override
public void f() {
//something
}
#Override
public void g() {
//something
}
}
public class Titi implements TheFGFunctions {
#Override
public void f() {
//something
}
#Override
public void g() {
//something
}
}
public class Toto {
private TheFGFunctions c;
public Toto(TheFGFunctions c) {
this.c = c;
}
public void notStaticFunction() {
c.f();
c.g();
}
}
This way is totally typesafe with zero exceptions to deal with!
You cannot access a static method polymorphically. The Java language doesn't support it.
The reason your current approach fails is that c is an instance of the class Class, and the class Class doesn't define methods f() or g().
(The methods that it does define are listed in the javadoc for Class. Note that Class is final so you can't create a custom subclass with extra methods.)
The simple alternative is to use reflection; e.g.
Class c =
Method f = c.getMethod("f");
f.invoke(null); // because it is static
But note:
This is not statically type-safe. The compiler cannot tell when you make the mistake of trying to use a static f() on a class that doesn't have such a method.
There are a few exceptions that you need to deal with; e.g. missing methods, incorrect signatures, methods that are not static, methods that don't have the correct access.
Other answers have proposed creating an interface and wrapper classes to make certain static methods dispatchable. It will work and it will be compile-time type-safe (!) but there is a lot of boiler plate code to write.
#Michael Michailidis commented:
Thus interfaces!
Yea ... kind of. You can only dispatch polymorphically on instance methods declared on an interface. That implies that you must have an instance of Tata or Titi, and call the methods on it. My reading of the Question is that the author wants to avoid that.
(IMO, the avoidance is the real problem. You are better of not trying to avoid instance methods.)
FWIW, you can declare static methods in an interface (since Java 8), but they would behave the same as if you declared them in a class. You wouldn't be able to dispatch ...
You could use reflections:
private Class c = Tata.class;
public Toto() throws Exception {
c.getMethod("f").invoke(null);
c.getMethod("g").invoke(null);
}
Here my Tata class
public class Tata {
public static void f() {
System.out.println("ffff");
}
public static void g() {
System.out.println("gggg");
}
}
Output on new Toto() call:
ffff
gggg
Update (call with parameters):
public Toto() throws Exception {
c.getMethod("f", String.class).invoke(null, "paramValue1");
c.getMethod("g", String.class).invoke(null, "paramValue2");
}
public class Tata {
public static void f(String param1) {
System.out.println("ffff " + param1);
}
public static void g(String param2) {
System.out.println("gggg " + param2);
}
}
Output:
ffff paramValue1
gggg paramValue2
Write a wrapper interface
interface CWrapper {
void f();
void g();
}
and wrapper class factory method for each Class containing the methods
class CWrappers {
CWrapper forTiti(Class<Titi> titiClass) {
return new CWrapper() {
void f() { Titi.f(); }
void g() { Titi.g(); }
}
}
// another factory method for Tata
}
Then you can use that:
public class Toto {
private CWrapper c = CWrappers.forTata(Tata.class); //or forTiti(Titi.class)
public static void main(String[] args) {
c.f();
c.g();
}
}

Cannot get value of property from extending class

I have two Java classes, one of which inherits from other. They are somewhat like the following:
A.java:
public class A {
public String invocations[] = {"foo"};
public A() {
// do stuff
}
}
B.java:
public class B extends A {
public String invocations = {"bar", "baz"};
public B() {
super();
}
}
In this example, assuming I create an instance of B and get its invocations property, it returns {"foo"} instead of the expected {"bar", "baz"}. Why is this, and how can I get the {"bar", "baz"}?
You have one variable hiding another one. You can refer to a variable in a super class by using a cast to the type explicitly. (I am assuming you fix the syntax errors)
public class Main {
static class A {
public String[] invocations = {"foo"};
}
static class B extends A {
public String[] invocations = {"bar", "baz"};
}
public static void main(String... args) {
B b = new B();
System.out.println("((A)b).invocations=" + Arrays.toString(((A) b).invocations));
System.out.println("b.invocations=" + Arrays.toString(b.invocations));
}
}
prints
((A)b).invocations=[foo]
b.invocations=[bar, baz]

Effective design for related classes that use unrelated classes

I have following situation and would like to know the best way to design my solution
public abstract class A {
public abstract A getHelper();
public abstract void launchHandle();
public static A initHelper(String condition) throws Exception {
if ( condition == 'xyz') {
return C.getHelper();
} else {
return B.getHelper();
}
}
}
public class B extends A {
protected static A b;
#Override
public A getHelper() {
b = new B();
return b;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle");
}
public String getName() {
return "I am from Class B";
}
}
public class C extends A {
protected static A c;
#Override
public A getHelper() {
c = new C();
return c;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle from C");
}
public String getValue() {
return "I am from Class C";
}
}
**Executor class**
public class Executor {
public static void main(String[] args) {
A aa = a.initHelper(condition);
}
}
Now in the above approach, i am unable to access methods like aa.getName() from Class B OR aa.getValue() from Class C, which makes sense. However how to get these methods in executor class? Executor does not know anything about Class B & C and should not know. Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
Please help design this and what could be best way to solve this.
Thanks in advance.
Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
If you take a closer look at your code, you will notice that the only contract constant across all your classes is the launchHandle method (baring getHelper and initHelper which are simply used for instantiating the right subclass). There is no real relation between B and C other than the fact that their instantiation is controlled by A.
This is how I would consider approaching the problem :
Executor Factory
Make Executor an abstract class rather than making it the entry point of your program :
public abstract class Executor {
public abstract void performTask();
public static void execute(String condition) {
Executor executor = null;
if ( condition.equals("xyz")) {
executor = new AExector();
} else {
executor = new BExecutor();
}
executor.performTask();
}
}
Executor implementations
Create a different implementation for operating on B called BExecutor :
public class BExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from B");
//create or get data to perform the task on
B b = new B();
String name = b.getName();
System.out.println("I am from "+name);
}
}
Create a different implementation for operating on C called CExecutor :
public class CExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from C");
//create or get data to perform the task on
C c = new C();
String value = c.getValue();
System.out.println("I am from "+value);
}
}
Your main method can then look like this :
public static void main(String []args) {
Executor executor = Executor.execute(condition);
}
And for some reason, if you do find some common contract between B and C, you an always create an interface which both B and C can implement and use a reference of this interface instead of using a B or C reference.
Add getName and getValue to A as abstract methods.

Implement two interfaces in an anonymous class

I have two interfaces:
interface A {
void foo();
}
interface B {
void bar();
}
I am able to create anonymous instances of classes implementing either of these interfaces like so:
new A() {
void foo() {}
}
or:
new B() {
void bar() {}
}
I want to create an anonymous class that implements both interfaces. Something like (the fictitious):
new A implements B {
void foo() {}
void bar() {}
}
This obviously gives a compile error: "B cannot be resolved to a type".
The workaround is quite simple:
class Aggregate implements A, B {
void foo() {}
void bar() {}
}
I then use Aggregate where ever I would have used the anonymous class.
I was wondering if it is even legal for an anonymous class to implement two interfaces.
"An anonymous inner class can extend one subclass or implement one
interface. Unlike non-anonymous classes (inner or otherwise), an anonymous
inner class cannot do both. In other words, it cannot both extend a class and
implement an interface, nor can it implement more than one interface. " (http://scjp.wikidot.com/nested-classes)
If you are determined to do this, you could declare a third interface, C:
public interface C extends A, B {
}
In this way, you can declare a single anonymous inner class, which is an implementation of C.
A complete example might look like:
public class MyClass {
public interface A {
void foo();
}
public interface B {
void bar();
}
public interface C extends A, B {
void baz();
}
public void doIt(C c) {
c.foo();
c.bar();
c.baz();
}
public static void main(String[] args) {
MyClass mc = new MyClass();
mc.doIt(new C() {
#Override
public void foo() {
System.out.println("foo()");
}
#Override
public void bar() {
System.out.println("bar()");
}
#Override
public void baz() {
System.out.println("baz()");
}
});
}
}
The output of this example is:
foo()
bar()
baz()
For save some keystrokes (for example if the interfaces have a lot of methods) you can do this:
abstract class Aggregate implements A, B {
}
new MyObject extends Aggregate {
void foo() {}
void bar() {}
}
Notice the key is to declare the Aggregate as abstract.
Note that you can make a named local class that implements the two interfaces:
void method() {
class Aggregate implements A, B {
void foo() {}
void bar() {}
}
A a = new Aggregate();
B b = new Aggregate();
}
This save you from doing a class-level or top-level class declaration.
The result is called a local class. Local classes declared in instance methods are also inner classes, which means that they can reference the containing object instance.

Categories