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.
Related
class A {
public int a = 100;
}
class B extends A {
public int a = 80;
}
class C extends B {
public int a = 10;
public void show() {
int a = 0;
System.out.println(a);
System.out.println(super.a);
System.out.println(((A) this).a);
}
}
What does ((A) this).a in the line System.out.println(((A) this).a); do?
Is it upcasting/downcasting thisor is something else happening here?
I also tried System.out.println(this); and System.out.println((A)this); and they both have the same output. What exactly is happening here?
In the java programming language, we have classes. When we write java code, we create instances of those classes, for example:
Object o = new Object();
Object is a class. Writing new Object() creates an instance of that class. The above code declares a variable o and assigns it [a reference to] an instance of class Object.
In the terminology of the java programming language, we say that variable o has type Object.
In the code in your question, a variable that is assigned an instance of class C, really has three types.
It has type C.
It has type B since B is the superclass of C.
It has type A because it indirectly extends class A also.
In the context of the code in your question, this is a special variable whose type is C. Writing (A) this is telling java to relate to the variable this as if its type is A.
Class A cannot access its subclasses. Hence it is only aware of its class member a. Hence when you write this line of code...
((A) this).a
You are accessing the member of class A only.
System.out.println(a);a is the one from the show method of your C class → a = 0
System.out.println(super.a);a is the one from the super-class of C, which is B → a = 80
System.out.println(((A) this).a);First, you cast your C instance (this) into A, then you call a which is a member of the A class → a = 100
There is also something to consider : method will always take the more specialized one (except if super is used), where field will be taken directly from the type referenced (even if there is an extending class).
For example, if I add getA() in each classes :
class A {
public int a = 100;
public int getA(){
return a;
}
}
class B extends A {
public int a = 80;
public int getA(){
return a;
}
}
class C extends B {
public int a = 10;
public int getA(){
return a;
}
public void show() {
int a = 0;
System.out.println(a);
System.out.println(super.a);
System.out.println(((A) this).a);
System.out.println(getA());
System.out.println(super.getA());
System.out.println(((A) this).getA());
}
}
class Scratch {
public static void main(String[] args) {
new C().show();
}
}
I get the following output :
0
80
100
10
80
10
Which means that in the case of the method, except in the case of super.getA() which explicitly goes to the superclass, casting your C into a A doesn't change much for methods, as it impacts the field.
If you write something like obj.a, obj.getA() or someMethod(obj), Java somehow has to find the actual field or method to be used, based on the type or class of obj. There are two distinct dispatch mechanisms involved (plus the special construct super).
Dynamic dispatch (polymorphism, overriding): This is used when calling an instance method on the object, as in obj.getA(). Then the runtime class of the obj is examined, and if this class contains a getA() method, this is used. Otherwise, the direct parent class is examined for a getA() method, and so on up to the Object class.
Static dispatch: In cases like obj.a or someMethod(obj), the runtime class of obj doesn't matter. Involved is only the compiler, and from his knowledge of obj's type, he decides which field or method to use.
super dispatch: If you write super.getA() or super.a, your getA() method or a field is ignored, and instead the next-higher class in the hierarchy is used that contains such a method or field.
In your case you have 3 fields plus one local variable, all with the same name a. (By the way, it's a very bad idea to have such name conflicts in professional code.) We are inside a method show() declared in the C class. Let's have a look at some different expressions and what they mean here:
a references the local variable a. There's no dispatch needed, it's just that local definitions take precedence over fields.
this.a is a static-dispatch expression, so it's important what the compiler thinks about the type of this. And that's always the class where this code has been written. In your case, it's class C, so the field a from class C is used, the one being 10.
super.a is a super-dispatch expression, meaning that the a field from this class C is ignored and the next higher one taken (the one from B, in our case).
((A) this).a is static dispatch, but the (A) casting has a significant effect. The expression before the dot originally comes from this, being of type C, but the (A) cast tells the compiler to believe it were of type A. This is okay, as every C also is an A, by inheritance. But now, static dispatch sees something of type A in front of the dot, and dispatches to the a field from the A class, and no longer from C.
getA(), this.getA() and ((A) this).getA() are all dynamic-dispatch examples, all giving the same result. The method called will be the one based on the runtime class of this object. This will typically be one defined in the C class. But if show() was called on an object of a subclass of C, e.g. D, and D had its own getA() method, that one would be used.
super.getA() is a case of super-dispatch, it will call the getA() method next higher up in the class hierarchy from the current class, e.g. B.
System.out.println(this);
And
System.out.println((A)this)
These two prints the object reference to class C with toString() method.
System.out.println(((A)this).a);
This is upcasting, child object to parent object.
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
Deitel's How To Program Java book says:
A final field should also be declared static if it is initialized in its declaration to a value.
Why is that?
public class A
{
private final int x = 5;
private static final int y = 5;
}
I think x and y are the same.
What does the static qualifier matter here?
What is the advantage of the static qualifier up there for software engineering observation?
x is an instance variable while y is global.
What does that mean?
Let's look at this example:
public class A {
public A() {
System.out.println("create A");
}
}
public class B {
public B() {
System.out.println("create B");
}
}
public class C {
private static B b = new B();
private A a = new A();
}
Then a main:
public static void main(String[] args) {
C c1 = new C();
C c2 = new C();
}
Which prints:
> create B
> create A
> create A
c1 and c2 shares the same instance of B while they both create their own instance of A!
So c1.b == c2.b while c1.a != c2.a.
So summary:
there is only one and the same place/address for field b for every instance of class C (c1, c2)
but for field a there are different places/addresses in the different instances.
The example is a bit oversized with class A and B:
Even for simple fields (int, float, ...) is one and the same place/occurrence for a static field in every instance of a class.
Since it is final, it will always hold the same value.
If you don't declare it static, you will create one variable for each instance of your class. Being static means you declare the variable only once, avoiding unnecessary memory usage.
Declaring a variable as static is more memory effecient. In your example for instance, no matter how many times you create a new A(), because fields x and fields y have been declared static, they will only be allocated memory once. If you do not declare them as static, they will be allocated memory with every new class instance.
It is sensible to declare a final variable that has been initialized like yours as static because it is not able to change, and thus allocating it memory just one time is acceptable.
Essentially, it's to save memory. If the constant is always the same no matter what, then you might as well make it static so that it doesn't get created for each object. You don't want to make it static, however, if the constant is not necessarily the same for each object (for example, if your constant is initialized somewhere in a constructor).
It saves memory as it only allocates for 1 copy of the variable. If you were to make a new instance for a non-static variable for it will make a new copy for that specified instance.
Since they are final they cannot be changed so it would make sense to make them static, so when you make new instances, nothing new is allocated for the variables since they can't even be altered.
I'm currently taking a Java course and have a question about polymorphism.
Given
public class A {
private int a1;
public A(){}
public A(int a1) { this.a1 = a1;}
}
class B extends A {
private int b1;
public B() {}
public B(int b1, int a1) {
super(a1);
this.b1 = b1;
}
}
class C extends B {
private int c1;
public C(){}
public C(int c1, int b1, int a1) {
super(b1, a1);
this.c1 = c1;
}
}
What would be the best way to assign to fields a1, b1, and c1, all in one swoop? My first guess would be to make an instance of C and call its three-arg constructor.
But what happens when each class contains 10s or 100s of data fields? Wouldn't this approach mean calling constructors with huge numbers of arguments, like
C(arg1, arg2, ..., arg100), setting k of C's fields, then making a call to
B(arg1, arg2, ..., arg100-k), and so on,
all the way up to the top? Is there a better way to proceed?
Having so many parameters is a definite code smell; in all probability you want to split the object up into smaller self-contained objects and/or or collections.
On the other hand, there is the Builder pattern, where you use a helper class to set all the parameters and it constructs the object for you, possibly sanity-checking that all required fields are set and there are no conflicts.
Not in this particular case because the fields in the parent classes are declared private.
If they were protected then you could set all 3 of them from the class C constructor. However this breaks encapsulation because if the constructor for B did something else after the value was assigned you'd have to duplicate that logic in C in order to not violate it's contract, and as you can imagine that gets very messy when you have more constructors or parent classes in the type tree.
Having multiple calls chained in the manner you proposed is the safest way at the cost of having to call all those constructors up the chain. I'd recommend profiling your code to see if this is actually a problem and not just a premature optimization.
What you're suggesting would work if you set the class fields to public. Class C will have a1 and c1, but won't be able to access them due to them being private.
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.