what is the best way to get other class of object reference?? - java

Sorry, i can't give better title.I have two class A and B.A class is singleton class.it always gives same object to whoever want it.Here B class always want that A object refenence. check follow code
class B
{
private A a;
B(){
this.a=A.getAObject();
}
public void process(String[] args)
{
a.sendData();//line 1
(or)
A.getAObject().sendData();//line 2
}
}
which is best way as mentioned above line 1 or line 2 as performance wise like that??

You can reference of one class to another class by making reference of the other class
In your code you do something like this :
class B {
private A a;
B(A a){
this.a=a; //refernce of a
}
public void display(){
a.getA(); //display method of a
}
}
class A{
public void getA(){
....
}
}

In many cases the differences will be insignificant.
But there would be scenarios like where you have to create a lot of instances of B. So in those scenarios there would be a performance impact since introducing a filed to that class means taking more memory when creating a instance.
If it is not a scenario like that, I think its better to assign it to a variable, since it will improve the readability of the code if you use that instance often in the class.

Related

Parameter vs field

I'm creating an abstract class with an abstract method example(boolean b, String s) that takes 2 parameters.
I want to create some methods for use inside that abstract method, but I need them to use those same parameters. So instead of constantly using foo(b,s), it would be nicer to just use foo().
I thought I could somehow store them in the class. However, my method is potentially spammed so it must not be slower.
public abstract class Example {
public abstract void example(boolean b, String s);
public void foo() {
// This method needs the parameters from the above method.
}
}
Possible solution:
public abstract class Example {
protected boolean b;
protected String s;
public abstract void example();
public void foo() {
// This method can now use 'b' and 's'
}
public void run(boolean b, String s) {
this.b = b;
this.s = s;
example();
}
}
If I use these parameters like in the last example above, will it make the process any slower?
Will it cause problems if a thread wants to use this method while another is not finished yet?
Before dealing with speed, let's deal with correctness:
Will it cause problems if a thread wants to use this method while another is not finished yet?
Assuming that both threads share the same object, the answer is "yes".
However, if you can make it so that each thread uses its own instance of your class, the answer would be "no", because re-assignments from other threads is possible only on shared objects.
If I use these parameters like in the last example above, will it make the process any slower?
Any speed difference between the two implementations would be minimal, falling into category of premature micro-optimizations. If saving parameters on the object makes sense from readability perspective, and if it does not create concurrency issues, do it; otherwise, keep using parameters.
If you have some methods which you want implementations of example() to use, and they need invocation-specific values of b and s, you can put those methods in an inner class:
class Example {
final class Inner {
final boolean b;
final String s;
Inner(boolean b, String s) {
this.b = b; this.s = s;
}
void foo() {
// This can use the values of b and s passed to run().
}
}
public abstract void example(Inner inner);
public void run(boolean b, String s) {
example(new Inner(b, s));
}
}
This is thread safe (with respect to b and s) because you're not storing the values in shared mutable fields.
Will it cause problems if a thread wants to use this method while
another is not finished yet?
Yes its a issue when more than two threads executing the same method and it will be race condition. Ideally you should not have any state in service class as you will run into issues in case of multiple threads
In terms of performance it wont have any impact
You should pass it as method parameters. If not possible due to some issue you can think of putting it in ThreadLocal
To answer your question:
If I use these parameters like in the last example above, will it make the process any slower?
Yes, anything executing within the code takes time. Setting the variables will take a nanosecond or two to execute; although this time increase it insignificant and not worth even considering.
Will it cause problems if a thread wants to use this method while another is not finished yet?
Depends.
Yes:
Do both threads share the object?
Do both modify the state of the object?
Do both threads concurrently access the object?
No:
Will the object be immutable.
Will the object be synchronized
If the object is used by both threads the way it is now, you will most likely occur problems.
I decided to create a class Execution that acts as an overlay to the parameters and also contains the methods that require those.
public class Execution {
public final boolean b;
public final String s;
Execution(boolean b, String s) {
this.b = b;
this.s = s;
}
public void foo(); // Uses 'b' and 's'
}
Abstract class:
public abstract class Example {
public abstract void example(Execution e);
public final void run(boolean b, String s) {
example(new Execution(b, s);
}
}
Implementation:
public class ExampleExample extends Example {
#Override
public void foo(Execution e) {
/*
* Do whatever you want because
* you have 'b', 's' and 'foo()'
* and whatever methods
* added to 'Execution'
*
*/
}
}
I don't know how it will affect the performance, doing it this way. But it solved the dilemma.
Thanks for all your suggestions!

Method main is never used locally! Why?

I am taking a class in java and have some problems with this code: It says that classOne and the main String are never used locally. Why?
public class classA {
private static class classOne{
protected static int a;
protected static String b;
public Haustier (int x, String y){
a= x; b = y;
}
void print (int a, String b){
System.out.println("this is a result "+a+" . This is also a "+b+" result.");
}
public static void main(String[] args){
classOne H1 = new classOne(4, "Fluffy");
classOne H2 = new classOne(3, "Lessi");
H1.print(a, b);
H2.print(a, b);
}
}
}
The question in a nutshell: Implement a class, a constuructor, a method and print the result via System.out.println.
(of cause there are more details, but this would be the short version.)
Thank you for your help.
I am having to make some guesses here: you wrote this code in an attempt to solve the problem of which you give a brief description?
I am going to guess that you did not know that, although it is legal to put one class inside another class, that it is somewhat advanced and not something you are liable to need for an introductory assignment.
Your ClassA is sufficient to solve the problem, there is no need to declare another class at all. Dispense with ClassOne altogether. You will need a main method in ClassA; that is where execution will start once you start the resulting java program. Separately, you can write a constructor for ClassA, and the main method of that class can invoke it to create an instance of the ClassA class. You could also implement a method for ClassA besides main; you can just declare it public void printValue() or something like that, and then call it using the variable holding the ClassA instance that you created. Those two lines would look something like this:
ClassA classAInstance = new ClassA(); // here you are using your constructor
classAInstance.printValue(); // here you are calling your method.
See if you can put the rest of it together yourself. Good luck

There is any way to make two objects "siblings" without parent? [JAVA]

Ok, maybe I´m asking a total nonsense here, but here is the deal.
I have two java clases A and B that comes from different libraries, that looks somethink like
public class A {
method1()
}
public class B {
method1()
method2()
}
Later, I want something like
if (condition)
temp = new A()
else
temp = new B()
so later I´ll be able to use
temp.method1()
without thinking if its A or B
I guess that if A and B inherits from a parent C, this would be easy, but that´s not the case neither I can change it...
So... is there a elegant way to solve this?
I´m mapping both objects into a third one, but I find it cumbersome. So... any ideas?
I would consider making wrapper interfaces & classes around the base classes.
For example make interface Method1 { method1(); } and then make:
class AMethod1 implements Method1 {
A a;
method1() { a.method1(); }
}
with appropriate constructors & what not.
You can try extending both of these class and then you can have full control over them, and then make them implement single interface
You can either try answer provided by #Jigar Joshi or instead of extrending those classes you can write wrappers for them that would implement the same interface.
Check Adapter pattern. This allows you to make incompatible interfaces compatible.
With the Adapter pattern you do not exterd the classes. Instead, you write a new class implementing your interface and forwarding (delegating) the call to the real object.
You can use reflection.
public static void invokeMethod1(Object o) throws Exception {
o.getClass().getDeclaredMethod("method1").invoke(o);
}
public class Wrapper {
public Wrapper(A a)
{ this.a = a }
public Wrapper(B b)
{ this.b = b }
public void method1()
{
if(a == null)
b.method1();
else
a.method1();
}
}
A bit brute force, but it would work.

Java calling method on all objects of specific type

Okay, the title is a little bit cryptic, an example will show better what I mean, suppose the following structure:
interface I {
methodCall();
}
class A implements I {
}
class B implements I {
}
class C implements I {
}
class Main {
private A a;
private B b;
private C c;
//other interesting stuff
void doSomeMainMethod() {
a.methodCall();
b.methodCall();
c.methodCall();
}
}
This code has been heavily simplified, the classes A, B and C implement methodCall() obviously, but there is no need to explicitely show that in the code.
What I want to ask is the following:
Is there a way to tell Java to generate my doSomeMainMethod method? I want to tell Java to call methodCall() on all objects of type I in class Main.
Preferably without the use of reflection, because with reflection I think it is possible or if reflection is needed, is there a way to wrap it up such that it at least looks non-hackish? Ofcourse it needs to be safe (as safe as possible) aswell.
class Main {
private A a;
private B b;
private C c;
private I[] instances = new I[]{a, b, c};
//other interesting stuff
void doSomeMainMethod() {
for(I instance : instances) {
instance.methodCall();
}
}
If you want the method to be generated then you can use ASM generation or (probably simpler option) implement your own AnnotationProcessor. With the second option you should annotate your classes and then scan for this annotation in compile time and generate decired method.
interface I {
void methodCall();
List<I> INSTANCES = new ArrayList<I>();
}
Now, in every constructor of classes that implements interface I, do this:
I.INSTANCES.add(this);
In main:
for (I i : I.INSTANCES) {
// do something with every instance of I
}
EDIT:
This will add all instances of I. To limit it to the objects created in Main, let´s add a parameter, createdBy. It is not quite elegant, but it is just Java, no Reflection ...
public A(Class createdBy) {
if (createdBy.equals(Main.class) {
I.INSTANCES.add(this);
}
}

Accessing a parents methods and variables correctly?

So this may be a very simple question that I'm overthinking but if I do something like the following:
class A{
public String test_string = "before (default)";
public A(){
B b = new B(this);
}
public void testA(){
this.test_string = "after (new)";
}
}
where B is:
class B{
private A parent;
public B(A mParent){
parent = mParent;
}
private void testB(){
System.out.println(parent.test_string);
}
}
Would that allow me to still access the same instance of A (all of its public fields and methods)? If I called A.testA() from another class somewhere else on that specific instance of A, would the B that was constructed in that A's constructor's testB function return the "after (new)" string? Or would that be a copy of A because doesn't java assign by value, not reference? Is there a better way of doing this? Am I just over complicating the issue?
I wasn't sure what to search for so I couldn't find other questions that answered my question.
Thanks in advance!
It is breaking encapsulation to have public fields in a class and access them. Please wrap them in accessors if you must have them.
Besides, if you stick by the "tell don't ask" rule, then actually your code would be:
private void testB(){
parent.printTestString();
}
and in A you'd have
public void printTestString(){
System.out.println(test_string);
}
In answer to your question
"Would that allow me to still access the same instance of A (all of its public fields and methods)? If I called A.testA() from another class somewhere else on that specific instance of A"
Yes it would if it was the same instance.
"would the B that was constructed in that A's constructor's testB function return the "after (new)" string?"
Yes it would, the member field would be pointed to a new string reference so any usage of that instance of A would get the same value (threadsafety notwithstanding)
Yes, it is the same instance. It works like shown in this image:
So, calling a method over b.parent.foo, it is called over the same instance passed in the constructor.

Categories