I'm just getting the hang of OOP and have been playing around with Java a lot. One of the troubles I have is deciding whether I need a private instance field for a particular class. Is there a rule of thumb I should be using in terms of whether I need to make something a private instance field of not?
Thanks.
Well, ask yourself whether it's logically part of the state of an instance of the object. Is it something about the object which is valid for the whole lifetime of the object, or is it something which only applies during the course of a single method (in which case it should be a local variable)? Or is it actually applicable to the class itself (in which case it should be static)?
If you could give some examples where you aren't quite sure, that would help.
(Note that I've assumed that the choice here is the kind of variable - static, instance or local. Instance variables should pretty much always be private :)
If it´s a natural part of the object or something the object needs to perform some task on a regular basis then by all means make it an attribute. If it is a constant then you should make it a public class variable (or rather a constant :P). That is, declare it "public static final w/e"
Public instance variables are not used as often because it often leads to messier code. Think as previously stated of the instance variables (or attributes) as the objects state. It´s usualy clearer to change the objects state by performing operations on it rather than juggle publics around. Good luck.
"Avoid public fields except for constants. (Many of the examples in the tutorial use public fields. This may help to illustrate some points concisely, but is not recommended for production code.) Public fields tend to link you to a particular implementation and limit your flexibility in changing your code." Controlling Access to Members of a Class
When learning object-oriented programming, think of it as a way to model real-world concepts as code. Nouns become objects; and the actions done to, on or by the nouns become methods. Instance variables are the properties of those nouns. For instance if you have a class representing a Car, slamOnTheBreaks() would be a method the Driver would call to slam on the breaks, and a Car has some number of seats inside, right? So an instance variable would be int numberOfSeats;.
Think of instance variables on a need-to-know, need-to-change basis. By making numberOfSeats public, that would allow the Driver to change the number of seats in the car, which doesn't make any sense. They only need to know how many seats the car has, which they can find out when they get in the car, or rather, calling the method public int getNumberOfSeats().
As Danny mentioned, the story is different for constants. If a value is a constant, it will remain constant for the entire duration of the program's execution, so for example if you want Driver Bob to be the only Driver for all those Car and Truck objects you create, Bob had better be a.) accessible, a.k.a. public, so he can be in every Car and Truck (assuming no inheritance between Car and Truck), and b.) unable to change.
Related
I know that constants are those variables whose values cannot be changed, but if no part of the program changes their value, are they still required to be declared final? And it also seems that they must be static. Why is that?
You are actually asking several questions at once which I am trying to answer.
Why use constants at all?
Constants are used to avoid magic numbers/strings in your code. If you have a string that appears in several occasions of your code, once you have to change that string you only need to change the constant definition and not every occurrence of the string in your code. Also if a constant is only used once it is often a good thing because of its better visibility.
The final keyword.
Its purpose (at least in this context) is twofold. One is to make it impossible to a programmer to change the value. You might have forgotten that it is a constant. The other is to tell the compiler that the value cannot change at runtime. This can be used to create optimized bytecode (e.g. the constant could be removed and every occurrence replaced by its value by the compiler).
The static keyword.
In Java everything is a Class. And every Class can have several instances (objects). If you dont mark your constant as static then every object has "its own constant". Since you dont want that it makes sense to mark it as static. Static fields (or methods) do exist only once per class (as opposed to once per object of the class).
It is certainly possible to declare non-static finals:
class Employee {
final String empId;
public Employee(String empId) { this.empId = empId; }
}
In other cases you want the field to be constant across all instances of the class:
class Color {
final static int BLACK = 0xFFFFFF;
}
As to why you want to declare them final at all instead of just not changing them ever,
It increases program readability, it tells the reader of program something about its behavior that would otherwise have to be in documentation
Compiler reminds if you attempt to change it by mistake
Because static belongs to class rather than any instance.
When it is static single copy shared across all the instances. Where as instance member have the individual copy.
consider you need to increase/decrease game score (count), in each stage (Stage class) of your game.
Normally when you're going to use a constant value on your code, you declare a final static variable. That prevents you from spreading "magic values" around the code, which is not a good practice, for mantainability and legibility reasons.
If you don't declare them final, code made by other people (or you, in case you forget your initial intention) may modify the variable.
If you don't declare them static, every instance of the class you create will have a copy of it, also you'll have to create an instance to get the value. That's not what you want, usually.
We declare constants because we will always need some "magic numbers" that are fixed in the code. Using constants means that they are easier to spot, and that when you change them you will change all of them with a edit.
Imagine that your code defines that your window will show 15 records, and that you will consider people as adults when they are 15 years old. Without constants, changing the size of the windows means that you will have to find the 15 ocurrences, do not miss any, and do not change a 15 that means age by mistake.
The static part is because you do not want to instantiate an object to get a data that is not related to a particular instance (that is exactly what static means, btw, not only when used for constants).
It's not strictly necessary, but it's recommended for reasons of memory-efficiency:
If you don't declare your constant as static every instance of the class (possibly thousands of them) that is created will keep it's own value of (or at least a reference to) that constant in memory, whereas a static member is only kept once per class - and since it's constant anyway, that's sufficient.
That's pretty self-explanatory. In Java, (and all OO languages I suppose) should I declare instance method when it's the only choice or generally we don't care about it?
Methods are static when you dont need them to know about class state to process something. Helper methods are good examples of this scenario.
DateUtils.getDateNowInGMT()
The method above does not need any state to give you an answer. The one below does.
Withdrawer w = new Withdrawer.Builder().account(12545).build();
w.withdraw(100);
You cannot withdraw() money without knowing the account number, which is state associated with the Withdrawer. You could argue of course that this could be a static method and passing account information to the method would solve the problem, but it would make it inconvenient since all other methods need the same account information.
Generally speaking it will be more difficult for you to unit test your code if you use a lot of static methods (people consider it easier to mock an object using something like Mockito than mock a static method using something like Powermock).
However, if you do not care about that, and the method uses no instance data of the class it's in, you may as well make it static.
Yes.
That's the correct approach and at least I follow that.
For example, the utility methods should be made static.
But, mostly there are many future requirments and changes required, and we can't forsee all of them today. so instance should be preferred over static. until unless you are following some design pattern.
as such you can go with any kind of implementation. But rather than possibility, the criteria should be the requirement.
if you have some operations to be performed class-wide u should opt for static methods. say for example, if you have to generate some uniqueID per instance, or you have to initialize any thing that the instances would use like display or db-driver.
in other cases, instance methods are preferred where operations are instance specific.
Methods should be made static only when it makes sense for them to be static. Static methods belong to the class and not to the specific instances of it. Static methods can only use other static features of the class. A static method could not call an instance method or access instance variables for example. If this makes sense for the method you are designing, then it is a good idea to use static.
Also static elements, be it variables or methods, are loaded into memory at class loading time and stay there until the end of execution or when the class-loader unloads/reloads the class it belongs to.
I use Static methods when they are meant to do computations that do not fit in the general object oriented modeling of my application. Usually utility methods such as methods to validate input data or to hold information specific to the entire application execution, or to access points to external databases are good candidates for this.
As best of my knowledge,
If you have such a code or logic that utilize or yield something that is related to particular object state, or in simple words if your logic in side method treats different objects with some different sets of inputs and produces some different set of output, you need to take this method as instance method.
On the other side if your method has such a logic that is common for each object and the input and output doesn't depends upon object's state you should declare it as static but not instance.
Explaination with examples:
Suppose you are organizing a college party and you have to provide a common coupon to the students of all departments,you just need to appoint a person for distributing a common coupon to students(without knowing about his/her department and roll no.) as he/she(person) approaches to the coupon counter.
Now think if you want to give the coupons with different serial numbers according to the departments and roll number of students, the person appointed by you need to get the department name and roll number of student(as input from each and every student)
and according to his/her department and roll number he will create a separate coupon with unique serial number.
First case is an example where we need static method, if we take it as instance method unnecessary it will increase the burden.
Second case is an example of instance method, where you need to treat each student(in sense of object) separately.
This example may looks silly, but I hope it will help you to understand the difference clearly.
I read Effective Java, and there written
If a class cannot be made immutable, limit its mutability as much as
possible...
and
...make every field final unless there is a compelling reason to make it
nonfinal.
So need I always make all my POJO(for example simple Bookclass with ID, Title and Author fields) classes immutable? And when I want to change state of my object(for example user change it in table where represented many Books), instead of setters use method like this:
public Book changeAuthor(String author) {
return new Book(this.id, this.title, author); //Book constructor is private
}
But I think is really not a good idea..
Please, explain me when to make a class immutable.
No, you don't need always to make your POJO immutable. Like you said, sometimes it can be a bad idea. If you object has attributes that will change over the time, a setter is the most comfortable way to do it.
But you should consider to make your object immutable. It will help you to find errors, to program more clearly and to deal with concurrency.
But I think you quoting say everything:
If a class cannot be made immutable, limit its mutability as much as
possible...
and
...make every field final unless there is a compelling reason to make
it nonfinal.
That's what you should do. Unless it's not possible, because you have a setter. But then be aware of concurrency.
In OOP world we have state. State it's all properties in your object. Return new object when you change state of your object guaranties that your application will work correctly in concurrent environment without specific things (synchronized, locks, atomics, etc.). But you always create new object.
Imagine that your object contains 100 properties, or to be real some collection with 100 elements. To follow the idea of immutability you need copy this collection as well. It's great memory overhead, perhaps it handled by GC. In most situation it's better to manually handle state of object than make object immutable. In some hard cases better to return copy if concurrent problems very hard. It depends on task. No silver bullet.
1. A POJO is one which has private Instance Variables with Getter and Setter methods.
2. And Classes like String class, which needs a constant behavior/implementation at all time needs to be
final, not the one which needs to change with time.
3. For making a class immutable, final is not only the solution, One can have private Instance variables, with only Getter methods. And their state being set into the Constructor.
4. Now depending on your coding decision, try to rectify which fields needs to be constant throughout the program, if you feel that certain fields are to be immutable, make them final.
5. JVM uses a mechanism called Constant folding for pre-calculating the constant values.
I have a global boolean variable which I use to disable all trading in my financial trading system.
I disable trading if there is any uncaught exception or a variety of other conditions (e.g. no money in account).
Should this variable be static or an instance variable? If its an instance I will need to add it to constructors of loads of classes...Not sure if its worth the hassle.
Thxs.
If it's an instance, then you probably want it to be a Singleton, and you'll provide a public static getter (or a factory, or DI if you care about testing).
If you access it from multiple threads, then it'd better be an AtomicBoolean in both cases.
Throughout your entire career, the number of times that you will have a valid use for a global variable will be countable in the fingers of one hand. So, any given time you are faced with a "to global or not to global" decision, most chances (by far) are that the correct answer is NOT. As a matter of fact, unless you are writing operating system kernels and the like, the rule of thumb should be "do not, under any circumstances, make any variable whatsoever, anywhere, anytime, global."
Note that wrapping access to a global variable in a global (static) method is just fooling yourself: it is still just a global variable. Global methods are only okay if they are stateless.
The link provided by #HermantMetalia is a good read: Why are static variables considered evil.
In your case, what you need is probably some kind of "Manager" object, a reference to which you pass as a construction time parameter to all of your major logic objects, which, among other things, contains a property called "isTradingAllowed" or something like that, so that anyone interested in this piece of information can query it.
I'd put it in a static field. But prefer to make it an AtomicBoolean to prevent threading issues :-)
public class TradeMaster {
private static final AtomicBoolean TRADING_ALLOWED = new AtomicBoolean(true);
public static void stopTrading() {
TRADING_ALLOWED.set(false);
}
public static boolean isTradingAllowed() {
return TRADING_ALLOWED.get();
}
}
Static Pros:
No need to pass references to instance to every class which will be using this
Static Cons:
May lead to difficult in testing - I think it should be fairly easy to test a static variable if you set the state of the variable before and after the test (assuming the tests are not running concurrently).
Conclusion:
I think the choice here depends on what your view of testing static variables is...For this simple case of one variable managing the state I really cant see the problem with using static. On the otherhand...its not really that hard to pass an instance to the constructors of the dependent classes so you dont really have any downside when using the instance approach.
It should be static since it will be shared by all the instances of
this class.
It should be static since you dont want to have a separate variable for all the objects.
Given that I would suggest that you read some good resources for static variable usage they work like charm unless you mess them..
If you want to make a variable constant for the class irrespective of how many instances are creted then use static method. But if the variable may change depending on the use by different instance of class then use instance variable.
Example
*
Here is an example that might clarify the situation. Imagine that you
are creating a game based on the movie 101 Dalmations. As part of that
project, you create a Dalmation class to handle animating the various
Dalmations. The class would need instance (non-static) variables to
keep track of data that is specific to each Dalmation: what its name
is, how many spots it has, etc..
*
But you also need to be able to keep track of how many Dalmations have
been created so you don't go over 101. That can't be an instance
variable because it has to be independent of specific Dalmations. For
example, if you haven't created any Dalmations, then this variable has
to be able to store zero. Only static variables exist before objects
are created. That is what static variables are for - data that applies
to something that is beyond the scope of a specific instance of the
class.
I am new to programming. I am learning Java now, there is something I am not really sure, that the use of private. Why programmer set the variable as private then write , getter and setter to access it. Why not put everything in public since we use it anyway.
public class BadOO {
public int size;
public int weight;
...
}
public class ExploitBadOO {
public static void main (String [] args) {
BadOO b = new BadOO();
b.size = -5; // Legal but bad!!
}
}
I found some code like this, and i saw the comment legal but bad. I don't understand why, please explain me.
The most important reason is to hide the internal implementation details of your class. If you prevent programmers from relying on those details, you can safely modify the implementation without worrying that you will break existing code that uses the class.
So by declaring the field private you prevent a user from accessing the variable directly. By providing gettters and setters you control exactly how a user may control the variable.
The main reason to not just make the variable public in the first place is that if you did make it public, you would create more headaches later on.
For example, one programmer writes public getters and setters around a private member variable. Three months later, he needs to verify that the variable is never "set" to null. He adds in a check in the "setFoo(...)" method, and all attempts to set the variable will then be checked for "setting it to null". Case closed, and with little effort.
Another programmer realizes that putting in public getters and setters around a private member variable is violating the spirit of encapsulation, he sees the futility of the methods and decides to just make the member variable public. Perhaps this gains a bit of a performance boost, or perhaps the programmer just wants to "write it as it is used". Three months later, he needs to verify that the variable is never "set" to null. He scans every access to the variable, effectively searching through the entire code base, including all code that might be accessing the variable via reflection. This includes all 3rd party libraries which has extended his code, and all newly written modules which used his code after it was written. He then either modifies all calls to guarantee that the variable is never set to null. The case is never closed, because he can't effectively find all accesses to the exposed member, nor does he have access to all 3rd party source code. With imperfect knowledge of newly written modules, the survey is guaranteed to be incomplete. Finally he has no control over the future code which may access the public member, and that code may contain lines which set the member variable to null.
Of course the second programmer could then break all existing code by putting "get" and "set" methods around the variable and making it private, but hey, he could have done that three months earlier and saved himself the explanation of why he needed to break everyone else's code.
Call it what you will, but putting public "get" and "set" methods around a private member variable is defensive programming which has been brought about by many years (i.e. decades) of experience.
Anything public in your class is a contract with the users of the class. As you modify the class, you must maintain the contract. You can add to the contract (new methods, variables, etc.), but you can't remove from it. Idealy you want that contract to be as small as possible. It is useful to make everything private that you can. If you need direct access from package members, make it protected. Only make those things public which are required by your users.
Exposing variables means that you are contracting forever, to have that variable and allow users to modify it. As discussed above, you may find you need to invoke behaviour when a variable is accessed. This can be be done if you only contract for the getter and setter methods.
Many of the early Java classes have contracts which require them to be thread safe. This adds significant overhead in cases where only one thread can access the instance. Newer releases have new classes which duplicate or enhance the functionality but drop the syncronization. Hence StringBuilder was added and in most cases should be used instead of StringBuffer.
Its considered bad mainly because you loose control over who can change the value and what happens when the value changes.
In tiny application written by you for you it won't seem that important but as you start developing for larger and larger applications having control over who changes what and when becomes critical.
Imagine from your example above, you publish library as is, other people use it, then you decide you wanted to calculate another value in your bad class when the size changes ... suddenly the bad00 class has no way of knowing and you can't change it because other people rely on it.
Instead if you had a set method you could extend it to say
void SetSize(int newSize)
{
size = newSize;
DoCalculation;
}
You can extend the functionality without breaking other peoples reliance on you.
I highly recommend the book Effective Java, it contains a lot of useful information about how to write better programs in Java.
Your question is addressed in items 13 and 14 of that book:
Item 13: Minimize the accessibility of classes and members
Item 14: In public classes, use accessor methods, not public fields
You shouldn't allow implementations to alter your records directly. Providing getters and setters means that you have exact control over how variables get assigned or what gets returned, etc. The same thing goes for the code in your constructor. What if the setter does something special when you assign a value to size? This won't happen if you assign it directly.
It's a common pet-peeve of many programmers - Java code with private fields and public accessors and mutators. The effect is as you say, those fields might as well been public.
There are programming languages that voice for the other extreme, too. Look at Python; just about everything is public, to some extent.
These are different coding practices and a common thing programmers deal with every day. But in Java, here's my rule of thumb:
If the field is used purely as an attribute, both readable and writeable by anyone, make it public.
If the field is used internally only, use private. Provide a getter if you want read access, and provide a setter if you want write access.
There is a special case: sometimes, you want to process extra data when an attribute is accessed. In that case, you would provide both getters and setters, but inside these property functions, you would do more than just return - for example, if you want to track the number of times an attribute is read by other programs during an object's life time.
That's just a brief overview on access levels. If you're interested, also read up on protected access.
This is indeed used to hide the internal implementation. This also helps is providing extra bit of logic on your variables. Say you need to make sure that the value passed for a varable should not be 0/null, you can provide this logic in the set method. Also in the same way you can provide some logic while getting the value, say you have a object variable which is not initialised and you are accessing that object, in this case you cand provide the logic to null check for that object and always return an object.
C# programmers use this equally as much, or maybe more frequently than I see in Java. C# calls it properties where in Java it is accessors/mutators
For me it makes sense to have getter and setter methods to encapsulate the classes so that no class can change the instance variables of another class.
Okay. We are talking about Objects here. The real world objects. If they are not private,the user of your class is allowed to change. What if for a Circle class, and for the radius attribute/property of the Circle class, the user sets value as '0'. It doesn't make sense for a Circle to exist with radius as '0'. You can avoid such mistakes if you make your attributes private and give a setter method and in which and throw an Exception/Error (instructing the user ) that it is not allowed to create a Circle with radisu as '0'. Basically, the objects that are created out of your class - are meant to exist as you wished to have them exist. This is one of the ways to achieve it.
As stated earlier, the reason for making a variable private is to hide it from the outside. But if you make a getter AND a setter then you may as well make the variable itself public. If you find yourself later in a position that you made the wrong choice, then you must refactor your code from using the public variable into using the getter/setter which may not be a problem. But it can be a problem if other code, which you do not control, starts depending on your code. Then such a refactoring will break the other code. If you use getters and setters from the start you will reduce that risk in exchange for a little effort. So it depends on your situation.
It depends on who access these public variables. Most likely, only by people inside your company/team. Then it's trivial to refactor them into getters/setters when necessary. I say in this case, it's better to leave the variables public; unless you are forced to follow the java bean convention.
If you are writing a framework or a library intended for the public, then you shouldn't expose variables. It's impossible for you to change them into getters/setters later.
But the 2nd case is more rare than the first; people apply extremely unreasonable assumptions when it come to software engineer, as if they are not writing code, instead they are carving code in stone. And as if the whole world is watching while you code - in reality, nobody will ever read your code except yourself