I saw some piece of code looks like
public class A {
public void doSomething(B b) {
b.addSometing("queue1", getDefault());
b.addSometing("queue2", getDefault());
b.addSometing("queue3", getDefault());
}
private C getDefault() {
C c = new C();
c.setAutoCreate(true);
c.setExired(false);
c.setDelay(3500);
return c;
}}
if We put C c var. (which is default for all objects of class A ) for every object of class A , we just use a lot of memory for large of objects of class A, maybe better to make C c static ? We will create only one instance of class C for whole class and use it to every object of class A . If we do so ,after that code will like like
public class A {
private static C c = new C();
static {
c.setAutoCreate(true);
c.setExired(false);
c.setDelay(3500);
}
public void doSomething(B b) {
b.addSometing("queue1", c);
b.addSometing("queue2", c);
b.addSometing("queue3", c);
}
}
I think it's better way , perhaps I'm wrong . Please give me advise .
the answer to that question depends on the logic of the application and/or what A is supposed to do with the C instance. If just once instance of a particular object is required, I would suggest to use the Singleton pattern in Java https://en.wikipedia.org/wiki/Singleton_pattern .
However, if an instance of class A is changing its C member, it would be a bad idea to use the above-mentioned approach, because by changing the C member on one A object, you could interfere the computation that is done with, or on another A object.
If the C member contains configuration options or data that is used by all objects (as illustrated in the example above) and, hence, is not subject to change, You could use the singleton pattern to make it accessible for all A instances -- In my opinion that's fine.
Best,
Julian
Related
I can't modify either Class A or Class B. And both Class A & B are huge in size (with several nested Classes and hundreds of parameters). And with multiple threads, memory foot print is impacting the performance.I'm checking all ways to reduce memory usage. Basically I'm trying to limit the scope of Class B instance so that GC can work on it at the earliest.
(For Your Information: I already knew that I can do by B b = new B(); b.setS("Calm Down"); a.setB(b);)
Here is the scenario:
Class A{
private B b;
public getB{return b}
public void setB (B b){this.b = b;}
}
Class B{
private String s;
//getters and setters for s}
Class MyNeed{
A a = new A();
// Here I'm trying to create an obj B and set S and then pass that obj to a.setB().
a.setB (new B().setS("Param S Set"));
}
So I guess that new B() is local to setB(). so in the very next line new B() is out of scope.
But this way in eclipse, I'm getting error that setB() can't accept void. I guess it is setS() returning void.
May be I'm missing some concepts. But I want to have something such simple. How to implement this.
You can try to have a constructor within the class A:
class A{
private B b;
public B getB(){
return b;
}
public void setB (B b){
this.b = b;}
}
public A(S s){
this.S = s;
}
}
So when you do a.setB(), you can just do a.setB(s) and that will set the object S for that A object.
a.setB (new B().setS("Param S Set"));
Ok, That statement starts by creating a new B instance, then it calls the setS method on that instance, passing it the string "Param S Set". Finally, it calls a.setB(...) passing the value returned by the setS() call.
As you already know, that doesn't work because setS() returns void.
May be I'm missing some concepts. But I want to have something such simple. How to implement this.
{
B b = new B();
b.setS("Param S Set");
a.setB(b);
}
What you are trying is wrong. setS() does not return B instance.
You will not save any resources by writing one-liners.
GC will also not clean anything if you set B to A as long as A has a reference to B.
I got it using builder design pattern. Thanks to #Builder by lombok.
Thank you all.
how to use getter setter in two different class
Class A{
int a = 10;
GetterAndSetter gs = new GetterAndSetter();
gs.setValue(a);
}
Class GetterAndSetter {
int a ;
public void setValue(int a){
this.a = a;
}
public int getValue(){
return a;
}
}
class B {
int c;
GetterAndSetter gs = new GetterAndSetter();
c = gs.getValue();
}
While printing c it gives null. And tell me if it is valid or not.
Whenever you write this
GetterAndSetter gs = new GetterAndSetter();
what you're doing is to create a new instance of GetterAndSetter. Two instances that you create won't have any connection between them.
Inside class A, you create a new instance, and set its value. Inside class C, you create a new instance, and read its value. But because you've got two different instances, the value you're reading isn't connected with the value you're setting.
This is roughly like:
I buy an envelope, and put some money inside it.
Later on, I want to get the money back, so I buy a new envelope, and look for the money inside it.
You have to be looking in the same envelope that you put the money in, if you want to find it!
In class A, your code creates a new instance of GetterAndSetter and sets a value to the property. In class B, however, your code creates again another new instance of GetterAndSetter , then gets the value.
The instances your code works with in classes A and B are not the same - hence you don't obtain the values set in A when trying to get it in B. The instance of GetterAndSetter created in B is not used anymore after the code in B exits.
To fix this, you need to pass a reference to the GetterAndSetter instance from class A to B. You can do this e.g. by passing it as a parameter to a method of B, or by creating a new instance of A in B and calling a method that provides an instance of GetterAndSetter.
An example of the first option (pass as parameter):
Class A{
...
GetterAndSetter createAndSet();
int a = 10;
GetterAndSetter gs = new GetterAndSetter();
gs.setValue(a);
return gs;
}
...
}
class B {
...
void getValueFromGetterAndSetter(GetterAndSetter gs) {
int c;
c = gs.getValue();
...
}
...
}
To connect the instances, we of course also need to have another piece of code (assuming instances of A and B exist already):
...
b.getValueFromGetterAndSetter(a.createAndSet());
...
You have used different reference. You should use same reference so that only you can access the value.
you need to understand the basics of oops, you have created one instance inside class A and you are trying to access in Class B which is possible only if you pass the reference of that object from Class A to B. In that case you have to have the instance of GetterAndSetter which you have created in Class A in Class B, instead you have created another new instance which will create new reference in memory, and the class variable a will be null.
In your code, both class A and B create new objects for GetterAndSetter. Hence they are not shared between these classes. Thats why you are getting null.
I wounder how your code print null for C. I think it would be "0" instead.
It is valid, here is what happens:
You create object gs in class A
Then you set the value of a of that object to 10
You then create another object gs in class B
Last but not least, you ask the object gs from class B what its value for a is.
Guess what, its NULL as you did not set its value anywhere so it wont return one.
Let's say we have class A as a parent class, and class C that extends it.
class A
{
void m()
{
System.out.println("A.m");
}
}
class C extends A
{
#Override
void m()
{
System.out.println("C.m");
}
}
What's the difference between reference A a and C c when we use them to point to the same object type, for example A a = new C(); and C c = new C();?
From this question: Java inheritance vs. C# inheritance, it looks like that as a and c points to object type of C, and there seems no difference in using them.
I tested this code, and they all prints C.m.
class inherit {
void x(A a)
{
a.m();
}
public static void main(String[] args) {
System.out.println("hello");
A a = new C();
C c = new C();
a.m();
c.m();
new inherit().x(a);
new inherit().x(c);
}
}
That depends what the object is going to be used for.
If what you actually need is an object that has A's interface(i.e. A's type), it's strongly recommended to use A a = new C();. This way it makes it clear that you want an A interface, not a C implementation. Later when you change your mind, you can safely change it to A a = new Another_Subtype_Of_A(); without breaking other code.
This is especially true when A is an interface(In your case, A is a class). For example, if you just want a list, List list = new ArrayList(); is clearly better than ArrayList list = new ArrayList();. That's called "programming to interface, not implementation".
If you're creating an object that specifically needs C's interfaces(esp. those not present in A), you'd better choose C c = new C();. If you write A a = new C() instead, sooner or later you still have to cast the object to C(because A doesn't have all of your desired interfaces), so why bother?
It's not about the runtime type of the variable. You may only know you have a Vehicle object at compile time and based on user input, that may be a GarbageTruck or SportsCar.
GarbageTruck t;
...
t = new SportsCar(); //can't do this!
// so we do this:
Vehicle t;
if(user.isFast()) {
t = new SportsCar();
} else {
t = new GarbageTruck();
}
Java is all about Interfaces and Implementations.
An Interface is simply a set of public fields (methods & properties) the describe how users can interact with a class that implements the interface.
An Implementation is the code that actually makes those methods and properties do something. An Implementation can be a class that implements an interface, or it could be a subclass of some other implementation.
When you instantiate a class, you're writing code like:
Interface a = new Implementation();
Often times, we wrap the Interface and the Implementation all together... put another way, when we define a class, whether we're explicitly implementing an interface or not, we're defining an Interface with every public method we write.
Thus, it's the Interface that affects what methods we can call, but it's the Implementation that affects what happens when we call them.
firstly A is parent class and C is child class when you do A a = new A() then object of A is created and hold by A handle. When you do C c = new C() then object ofC is creating and C handle holds it.. But when you do A a = new C() then object ofC is created and Ahandle holds it. It means all the properties ofC is now been used. Although handle ofA is used by properties (instance) of C are used. This us polymorphism. Now it will used all the overloaded methods of C and not of A
Usages as an example
The difference come when you create a large project having methods created for child classes
Assume you have hello method
public void hello(C c) { }
In future you have another class B which extends A.. in that case you cannot use hello as its argument is of type C.. And imagine you have many classes as a child of A which need to use such method (then how many such methods you will create). Polymorphism is the rescue
You create hello with A as argument
public void hello (A x) { }
and now you can use same method for all the children of A..
A c = new C()
A b = new B()
Now all can use hello
this is the beauty of polymorphism
I got a class Foo having a method doSomething that uses two class-related variables b and c that are expensive to get/create. My first version looks like this:
public class Foo {
private final A a;
public Foo(A a) {
this.a = a;
}
public void doSomething() {
final B b = a.getB();
final C c = b.getC();
for (int i = 0; i < 1000; i++) {
// do something with b and c
}
}
}
So I get the first object (type B) via a class variable a and the second object (type C) via the first object.
Now, since those variables are related to the class and the method is always called exactly one time (though not necessarily when creating an object of type Foo), I thought about making them class variables as well:
public class Foo {
private final A a;
private final B b;
private final C c;
public Foo(A a) {
this.a = a;
b = a.getB();
c = b.getC();
}
public void doSomething() {
for (int i = 0; i < 1000; i++) {
// do something with b and c
}
}
}
I'm not sure which version to use if any of those two. I somehow don't feel comfortable making those two variables class members since they can be retrieved from the existing class variable a. However, it would increase readability of the methods IMO.
You are absolutely right. If it increases readability, bu all means do it. However, I would ask you this: What is the purpose of Referencing A from within the class? Is it only for getting B and C?
In this case, I would just input B and C in Foo's constructor!
This way you even make it more readable by breaking the dependency on A and Making the dependency on B and C more explicit.
Also, consider whether you are using these variables in other methods in the class. If the answer is yes- it signals that they should be class members, However, if the class contains a lot of methods that do not use these variables, that might signal the opposite.
The general principle you should follow here is the principle of High Cohesion
generally speaking, if you can use a local variable, it is preferable to using a field.
Using a local variable
limits the variable to where it is used.
uses less memory.
is thread safe.
Why not just store instances of B and C in your class Foo? Do you reference A somewhere in your class? Otherwise, Storing both B and C as instance variables is no less memory efficient, since storing one A object contains a B and C object.
From my experience static (or class variable|field|method) usually became evil after some time and needs to be refactorred out except cases when this stuff is static by it's nature (Math.PI or Math.max() are examples or such static things). If those methods are doing some computation based on anything dynamic I would leave them as instance.
I want to know about the advantage in between the creating an object for sub class but assigning class A ref instead of assigning Class B ref. which is shown in line1,line2 below code
class A
{
int b=10;
}
class B extends A
{
int b=12;
}
class Test
{
public static void main(String[] args)
{
A a=new B(); //line1
//B a=new B();//line2
System.our.println(a.b);
}
}
If you're not going to need any methods specific to B, in other words, you're strictly going to use it as an A, it's an advantage for readability to state so.
But the main advantage comes to light when you use the general type in a method declaration:
public String resolveName(A a) { ... }
If you used B here for no good reason, then you would unnecessarily cripple your method. It could have worked for any A, but it works only for B.
try reading this: Polymorphism
In your short example there's no real advantage,.
But in general your question is about what polymorphism is good for?
And the answer goes back to the need of OOP methodology.
In short it gives you the ability to encapsulate and abstract the implementation from the usage, and can help you I the future to replace the implementation without a need to change the usage.
For more details see http://en.wikipedia.org/wiki/Polymorphism_(computer_science)
In that example, I don't think you can talk about an advantage (or disadvantage), because your two lines of code each do something very different.
If the type of variable a is A, then a.b refers to the field b with the value 10.
But if you change the type of a to B then a.b refers to a totally different field, the one declared inside B, with the value 12.
If instead b was a method, then the one declared in B would "override" the one declared in A, which is a very different situation. e.g.
class A
{
public int b() { return 10; };
}
class B extends A
{
public int b() { return 12; }
}
And the calling code would be:
A a=new B(); //line1
//B a=new B();//line2
System.our.println(a.b());
That is, we call the method b to get the return value. Now it makes no difference to the behaviour whether the type of a is A or B. What matters is the type of object that a refers to, which is always B and hence always has the behaviour defined in B, so it will print 12 regardless.
The advantage of this is that you can have a collection of objects (e.g. various kinds of vehicle) and they can be a mixture of cars, boats, trains etc. Each has its own implementation of the start method, so you can treat them all the same way.
Although generally it's clearer to define such methods in an interface, rather than a class. There is no general way to start a vehicle, so no reason to have a base class that has a meaningless implementation of start. Instead you just use an interface to declare the "shape" of the method without giving it any implementation.