Why is "Set()" function better than modifying public variable? - java

This one is bothering me for a while now :)
Suppose we have a variable - why is writing a Set function better practice than simply modifying variable's data (and setting the variable to be public instead of private)?
It's less coding that way and I can't see any "security" issues.

Sometimes when setting a variable, you may want to do something else with the given value other than instantly place it in the class's variable: for instance, you may want to validate it or update another value that is related.
Basically, it lets the class which owns that variable control what can be done to it, and the specific series of events that occur when it is altered.

It also needs to be mentioned that it is not always better to use "set" methods. Blind compliance with patterns may lead to overcomplicated code. If class acts as just simple (really simple) data container, then public access is often acceptable. In example, look at java.awt.Rectangle or at java.awt.Point classes.

It all has to do with object orientation and how strict you are in that doctrine. If you strictly follow all the guidelines, it is bad to directly use methods and identifiers from one class, by the other. Technically there is no objection.
This discussion is the same as the static - no static discussion. The (self proclaimed) guru, found that sacrilege, but you put your computer no obstacle in the way, if you put your whole program is static.

Related

Why can't I declare a static variable inside a non-static method? [duplicate]

In C/C++ we use static local variables for maintaining a method's state. But why it is not supported in Java?
Yes, I can use an static field for this purpose. But isn't it a bit weird to create a field for maintaining only one method's state?
You have found the only solution.
Java dropped a number of complexities from C++, and this was one of them.
Static variables scoped to a function do nasty things to you in concurrency (e.g. strtok is a famously nasty one to use with pthreads, for exactly this reason).
In general, what you want is an object with state. The function in question should then have an object-level variable. Then you can create instances that each maintain state.
Much easier to understand/maintain/etc.
If you truly need to maintain state as a singleton, then static fields are it.
The Java language spec doesn't seem to defend the omission of variables that correspond to C static variables.
Hiding state in class methods has a few drawbacks when seen from a Java perspective. Generally the existence of a function-level static variable isn't the sort of implementation detail that you'd want to expose outside of that function.
But the method's state is actually part of the class's state, and method-level static variables would have to be serialized / deserialized any time the object is persisted. This might not sound common, coming from a C background, so I'll note a few common examples.
Application server clusters can pass user session objects between nodes in order to provide fault tolerance.
JAXB could be used to marshall an object into an XML document
JPA can be used to persist object state to a database
If the variable's value is worth saving when the object is persisted, then there's a good chance that code outside of that class will need to reference that value. And suddenly that means defining access levels -- is a static variable in a public method automatically public? Or would a programmer have to declare it so?
We also have to think about extensibility. Would derived classes be required to implement the same static variable? Or would there be a reference to the variable from the function in the base class?
It's more likely that the C method that would use a static local variable would be a good candidate for a class in Java. It has state and hopefully exists for a single purpose. There's little drawback to encapsulating the functionality into an object, and it makes for a cleaner separation between transient values (such as local variables) and more long-term state.
Some of the other answers show why you might not want to have this. But you can also ask why from a historical perspective.
To answer this you have to start to see why C does have static local variables. C has much fewer means than Java and C++ to limit the scope of a variable, the only options for static data are 'inside the file' and 'everywhere'. So this provides an extra layer, to limit the scope.
An important aspect of C++ is compatibility with, so it is allowed in C++ as well. But it doesn't need local static scope as much anymore, because there are many other means to limit scope of static data. The use is not popular in (modern) C++.
Java merely takes a lot of inspiration from C/C++, it didn't have to worry about backwards compatibility, so it could be left out.
Perhaps because methods are not objects in Java; so maintaining their state as you said make not much sense and I guess you'd have to create a new concept in the byte code for that; use an object as Tony K. said.
instance methods are invoked by the instance(objects) of the class . Static things belongs to the class not to the object that's why local variables are not static.Instance variables are static and they can also initialized at the time of class loading by static blocks.
enter image description here
for more information please visit :- https://www.youtube.com/watch?v=GGay1K5-Kcs&t=119s

Is it better to use local or global variables

Is it better to use local or global variables?
Let's say talking about 2000+ lines of android(java) service class, and all service is working on 'request' object and similar shared objects.
If I make everything local(keep inside of function), I need to pass many variables every time, or override same function many times. I need to make sure that objects, and sub objects are not null too.
If I make some variables global(across the class) I can share them, use them across the functions. Which I think will make everything easier.
What are the good sides and bad sides of defining variables inside of function or defining globally. In practice, and in theory(readability etc).
Is there suggested way?
Thank you.
Always prefer local over global. If you need to pass the data in as multiple parameters, so be it. At least then you're explicitly saying what data your function depends on. Having too many parameters is certainly a problem, but offloading some of them as globals isn't the answer.
If you rely on globals, it may not be as clear where certain data is coming from. If the globals are mutable, you'll have a mess on your hands as soon as you start to try to debug a difficult problem since it may not be obvious when certain global variables are being modified.
Note though that immutable constant globals aren't bad. If you have a constant that's needed in many functions (like PI for example), it makes sense to make it global. Immutable constants don't suffer from the drawbacks mentioned above since they can't change.
You wrote a 2000+ lines of service class. You completed the project. Cool ! Now after a month, you got a bug reported and are required to fix it.
Lets go through 2 different cases :
CASE 1
You are back on the service code. You see that the func1() uses globalVariabl1. Okay, but whats its value by now ? How does it change ? Who mutates the globalVariabl1 before it comes to this function ? What have been the sequence of all these mutations ? You would have no idea. It will be quite difficult to figure all this out.
CASE 2
You are back to you code, and see that the func0() fetches something and then passes it to func1(param1) as a parameter. You clearly know what the data is, how does it gets here.
In what case will it be easier to resolve the bug ?
Most of the time, CASE 2 will make it lot easier.
Local variables
Local variables would always help you. Even when you write the code and using local variables, the call statement will itself tell you that this function depends on this particular data. It helps you to be careful about what you are passing around.
Global variables
Global variables are okay when they represent the state of the class/object, or even when they are Constant (which should in general be all UPPERCASE letters). They can also be good when you just need to access the value frequently, and you know that the variable will always be initialised when you use it (for example initialising it inside onCreate())
There are no global variables in Java. You are referring to member variables. The basic rule is that variables should have the smallest possible enclosing scope.
I know the question is already answered and I upvoted Carcigenicate's answer.
To elaborate on his point I would suggest you try Test Driven Development practices. As soon as you start writing your code in conjunction with Unit test you will realize how bad Global variables can be and you will realize that you are writing code that cannot be tested without having to implement unnecessary Dependency Injection.
One more thing. Global variables are a huge mistake any time you start dealing with multiple threads and concurrency. It doesn't sound like you are dealing with that but keep it in mind any time you decide to make a Global variable.
It all depends on the scope of the variable. If you feel that a certain variable will take multiple values by passing through various functions then use local variables and pass them in function calls.
If you feel that a certain variable you need to use will have constant value, then declare it as a global variable.

Why is making variables public visibility a bad practice

I am in a Introduction to Java class and I was doing a bit of research on variables. It seems that knowledgeable programers state that it is bad practice to define the variables in public visibility. I see them stating it is bad practice but I can not find a rhyme or reason to their claims. This is how I defined my variables in a application for my course.
public class DykhoffWk3Calculator
{
/*
* This class is used to define the variables in a static form so all
* classes can access them.
*/
public static double commissionRate = .03, startSalary = 45000,
accelerationFactor = 1.25;
public static double annualSales, commissionTotal, totalCompensation,
total, count, count2;
private static Object input; Object keyboard;
public static class UserInput
{ //Then continue with my other classes
I thought this was a logical method of defining them so all classes, not just main, could access them. Can someone explain to me why this is bad practice, and where variables should be defined? Any assistance would be greatly appreciated.
In short: because all of your public "surface area" for a class effectively defines its API.
If you expose things through methods, then you can change the details of how they work later. But if you expose a field, and some other class outside of your control (and quite possibly outside of your knowledge) starts referencing that field, then you're stuck with exposing that field for the rest of time. Or until you decide to break backwards-compatibility.
I thought this was a logical method of defining them so all classes, not just main, could access them.
As a general rule, you don't want "all classes" to access them. The vast majority of work with software, is spent maintaining code, not writing it for the first time. And so experienced developers realise that best practices for code, are generally the ones that make it most maintainable, not necessarily the ones that make it most convenient to write in the first place.
And if you have a variable that could be accessed from anywhere, at any time, and you want to make some tweaks to how it is modified - how can you be sure that this is safe? How long will it take you to track down all the ways that this is referenced, and determine what the effects of your change will be? (And specific to public fields, you can kiss goodbye to any sort of reusability regarding running at the same time from multiple threads, or running reentrantly.)
Broadly speaking, reducing the "surface area" of classes is a really good thing to do. Restricting the ways that other classes can interact with this one, makes it much easier to control and understand the relationships, as well as making it easier to make internal changes "invisible" to those other classes. Think about what this class does, what it will provide to other classes, as defining an interface (whether an actual interface or not). And only expose to other classes, the bare minimum that is required to fulfil those requirements.
And that never involves letting them have arbitrary access to variables.
So the general point is that you in fact DON'T want anyone to be able to access those values. Not only can I see those variables, but I can also change them to anything I like. This can lead to problems in larger, more complex programs.
Furthermore, if you wanted to later change how the class uses/stores these values, you couldn't without having to go out and change all the other classes that access those public variables directly. Instead, you should offer methods that provide just the amount of access that you want to give.
The standard analogy is that of driving a car. You know how to turn the wheel, hit the brake, etc, but not how the car actually does these things. So if the engine needed to be dramatically changed, or you got in a new car, then you'd still know how to drive. You don't need to worry about what's happening behind the scenes.
Firstly you state it wrong.
its bad to make your variable public i.e:
public String name = null; this is bad. You should always do it as
private String name = null;
To understand why, you need to dig a bit into the ideology of OOPs
OPPS ideology states that each object of your class will have 2 things:
Properties: something which we also call variables or state.
Behavior: something which we call methods or functions.
Properties identify the object over a period of time. Behaviors allow you to manage the properties of the object so that the same object over time can appear to be in different states.e.g: a Product object over a period of can be an 'Available line item' or 'Added to cart' or 'Sold' or 'Out of stock' depending on its state. Since state is critically important to the object so the object should not allow direct nonsense mutation operations on its state. Objects should keep their variables private to them and expose behaviors that the outside world can use to interact with the object and change the state based on the operation executed in the behavior. e.g: calling the 'addToCart()' behavior on the Product object that was in 'Available line item' state would probably mean: changing not just its state to 'Added to cart' but probably making other users aware that the number of this Products now available is 1 less.
So long story short: don't expose properties directly to outside work for mutation unless needed. This means dont make them public and also dont give setter methods if not needed.
By Convention Fields, methods and constructors declared public (least restrictive) within a public class are visible to any class in the Java program, whether these classes are in the same package or in another package.Which means that a change in the value of a field will definitely affect other classes accessing that field..thus breaking the whole sense of encapsulation.
Public variables in general in a class are a bad idea. Since this means other classes/programs, can modify the state of instances.
Since it is the responsibility of a class to protect its state and ensure the state is "consistent", one can enforce this by defining public setters (since this allows to run code to check/repair state).
By setting the variables public, the state is not protected. If later not all representable states are valid states, one has a problem.
Example:
Say you want to implement an ArrayList<T>, then it will look like (not fully implemented):
public class ArrayList<T> {
public int size = 0;
public Object[] data = new Object[5];
}
Now one can modify the size of the arrayList. Without adding an element. Now if you would ask the ArrayList<T> instance to remove/add/copy/...whatever, the data on which it works can be wrong.
Perhaps you can claim that a programmer is nice: he will not modify the object unless he needs to and according to the "rules". But such things eventually always go wrong, and what if you decide to modify your definition of the ArrayList (for instance using two int's for the size). In that case you would need to rewrite all code that sets such fields.
To conclude: private/protected is invented to protect a class instance from other instances that would turn the instance corrupt/invalid/inconsistent/...

Setting values of an object

Let's say I've got a class called House with the two fields
name
address
Each of these fields has got a getter and a setter.
Now I want another method in the House class called setValues. This method should set the fields with properties from a passed object of a different type.
There would be two ways on how to create this method. First way:
private void setHouse(HouseTransfer transer){
name = transfer.getName();
address = transfer.getAddress();
}
Or the second option:
private void setHouse(HouseTransfer transer){
setName(transfer.getName());
setAddress(transfer.getAddress());
}
Which one is more "best practice"?
At a certain level of granularity, software design is more subjective matter than one of black-and-white absolutes. I do not believe there is an absolute "best practice" here.
That being said, I personally would use the second form. The basic idea of having a setter method is that at some point you might need some some special logic around setting that value (e.g. formatting input, sanitation, validation, etc). So it makes the most sense to always rely on any such logic being in one central place, rather than scattered throughout you code anywhere this variable is set.
If you have a truly trivial example, where the setter is simply setting the value and know absolutely that no other logic will ever be added, then you could certainly use the first form for simplicity. Put there's not real performance hit to the second form, so I personally would just use that.
I would use the individual getters/setters inside of the setHouse method (which is your second option).
The fact that you have setters indicates that there is some kind of encapsulation involved around that operation. Rather than re-write the code to enforce that encapsulation, re-use what you already have.
Jon's answer to that question (Taken from another question about using getters/setters which is not a duplicate to this one)
You don't always need getters/setters, but if you have some, there's usually a good reason why you've implemented them and in that case: use them.
Perhaps if you are getting and setting in two different places you might consider factoring out your getter and setter to a common interface. This can make later customisations easier, right?

What is the reason for these PMD rules?

DataflowAnomalyAnalysis: Found
'DD'-anomaly for variable 'variable'
(lines 'n1'-'n2').
DataflowAnomalyAnalysis: Found
'DU'-anomaly for variable 'variable'
(lines 'n1'-'n2').
DD and DU sound familiar...I want to say in things like testing and analysis relating to weakest pre and post conditions, but I don't remember the specifics.
NullAssignment: Assigning an Object to
null is a code smell. Consider
refactoring.
Wouldn't setting an object to null assist in garbage collection, if the object is a local object (not used outside of the method)? Or is that a myth?
MethodArgumentCouldBeFinal: Parameter
'param' is not assigned and could be
declared final
LocalVariableCouldBeFinal: Local
variable 'variable' could be declared
final
Are there any advantages to using final parameters and variables?
LooseCoupling: Avoid using
implementation types like
'LinkedList'; use the interface
instead
If I know that I specifically need a LinkedList, why would I not use one to make my intentions explicitly clear to future developers? It's one thing to return the class that's highest up the class path that makes sense, but why would I not declare my variables to be of the strictest sense?
AvoidSynchronizedAtMethodLevel: Use
block level rather than method level
synchronization
What advantages does block-level synchronization have over method-level synchronization?
AvoidUsingShortType: Do not use the
short type
My first languages were C and C++, but in the Java world, why should I not use the type that best describes my data?
DD and DU anomalies (if I remember correctly—I use FindBugs and the messages are a little different) refer to assigning a value to a local variable that is never read, usually because it is reassigned another value before ever being read. A typical case would be initializing some variable with null when it is declared. Don't declare the variable until it's needed.
Assigning null to a local variable in order to "assist" the garbage collector is a myth. PMD is letting you know this is just counter-productive clutter.
Specifying final on a local variable should be very useful to an optimizer, but I don't have any concrete examples of current JITs taking advantage of this hint. I have found it useful in reasoning about the correctness of my own code.
Specifying interfaces in terms of… well, interfaces is a great design practice. You can easily change implementations of the collection without impacting the caller at all. That's what interfaces are all about.
I can't think of many cases where a caller would require a LinkedList, since it doesn't expose any API that isn't declared by some interface. If the client relies on that API, it's available through the correct interface.
Block level synchronization allows the critical section to be smaller, which allows as much work to be done concurrently as possible. Perhaps more importantly, it allows the use of a lock object that is privately controlled by the enclosing object. This way, you can guarantee that no deadlock can occur. Using the instance itself as a lock, anyone can synchronize on it incorrectly, causing deadlock.
Operands of type short are promoted to int in any operations. This rule is letting you know that this promotion is occurring, and you might as well use an int. However, using the short type can save memory, so if it is an instance member, I'd probably ignore that rule.
DataflowAnomalyAnalysis: Found
'DD'-anomaly for variable 'variable'
(lines 'n1'-'n2').
DataflowAnomalyAnalysis: Found
'DU'-anomaly for variable 'variable'
(lines 'n1'-'n2').
No idea.
NullAssignment: Assigning an Object to
null is a code smell. Consider
refactoring.
Wouldn't setting an object to null assist in garbage collection, if the object is a local object (not used outside of the method)? Or is that a myth?
Objects in local methods are marked to be garbage collected once the method returns. Setting them to null won't do any difference.
Since it would make less experience developers what is that null assignment all about it may be considered a code smell.
MethodArgumentCouldBeFinal: Parameter
'param' is not assigned and could be
declared final
LocalVariableCouldBeFinal: Local
variable 'variable' could be declared
final
Are there any advantages to using final parameters and variables?
It make clearer that the value won't change during the lifecycle of the object.
Also, if by any chance someone try to assign a value, the compiler will prevent this coding error at compile type.
consider this:
public void businessRule( SomeImportantArgument important ) {
if( important.xyz() ){
doXyz();
}
// some fuzzy logic here
important = new NotSoImportant();
// add for/if's/while etc
if( important.abc() ){ // <-- bug
burnTheHouse();
}
}
Suppose that you're assigned to solve some mysterious bug that from time to time burns the house.
You know what wast the parameter used, what you don't understand is WHY the burnTHeHouse method is invoked if the conditions are not met ( according to your findings )
It make take you a while to findout that at some point in the middle, somone change the reference, and that you are using other object.
Using final help to prevent this kind of things.
LooseCoupling: Avoid using
implementation types like
'LinkedList'; use the interface
instead
If I know that I specifically need a LinkedList, why would I not use one to make my intentions explicitly clear to future developers? It's one thing to return the class that's highest up the class path that makes sense, but why would I not declare my variables to be of the strictest sense?
There is no difference, in this case. I would think that since you are not using LinkedList specific functionality the suggestion is fair.
Today, LinkedList could make sense, but by using an interface you help your self ( or others ) to change it easily when it wont.
For small, personal projects this may not make sense at all, but since you're using an analyzer already, I guess you care about the code quality already.
Also, helps less experienced developer to create good habits. [ I'm not saying you're one but the analyzer does not know you ;) ]
AvoidSynchronizedAtMethodLevel: Use
block level rather than method level
synchronization
What advantages does block-level synchronization have over method-level synchronization?
The smaller the synchronized section the better. That's it.
Also, if you synchronize at the method level you'll block the whole object. When you synchronize at block level, you just synchronize that specific section, in some situations that's what you need.
AvoidUsingShortType: Do not use the
short type
My first languages were C and C++, but in the Java world, why should I not use the type that best describes my data?
I've never heard of this, and I agree with you :) I've never use short though.
My guess is that by not using it, you'll been helping your self to upgrade to int seamlessly.
Code smells are more oriented to code quality than performance optimizations. So the advice are given for less experienced programmers and to avoid pitfalls, than to improve program speed.
This way, you could save a lot of time and frustrations when trying to change the code to fit a better design.
If it the advise doesn't make sense, just ignore them, remember, you are the developer at charge, and the tool is just that a tool. If something goes wrong, you can't blame the tool, right?
Just a note on the final question.
Putting "final" on a variable results in it only be assignable once. This does not necessarily mean that it is easier to write, but it most certainly means that it is easier to read for a future maintainer.
Please consider these points:
any variable with a final can be immediately classified in "will not change value while watching".
by implication it means that if all variables which will not change are marked with final, then the variables NOT marked with final actually WILL change.
This means that you can see already when reading through the definition part which variables to look out for, as they may change value during the code, and the maintainer can spend his/her efforts better as the code is more readable.
Wouldn't setting an object to null
assist in garbage collection, if the
object is a local object (not used
outside of the method)? Or is that a
myth?
The only thing it does is make it possible for the object to be GCd before the method's end, which is rarely ever necessary.
Are there any advantages to using final parameters and variables?
It makes the code somewhat clearer since you don't have to worry about the value being changed somwhere when you analyze the code. More often then not you don't need or want to change a variable's value once it's set anyway.
If I know that I specifically need a
LinkedList, why would I not use one to
make my intentions explicitly clear to
future developers?
Can you think of any reason why you would specifically need a
LinkedList?
It's one thing to
return the class that's highest up the
class path that makes sense, but why
would I not declare my variables to be
of the strictest sense?
I don't care much about local variables or fields, but if you declare a method parameter of type LinkedList, I will hunt you down and hurt you, because it makes it impossible for me to use things like Arrays.asList() and Collections.emptyList().
What advantages does block-level synchronization have over method-level synchronization?
The biggest one is that it enables you to use a dedicated monitor object so that only those critical sections are mutually exclusive that need to be, rather than everything using the same monitor.
in the Java world, why should I not
use the type that best describes my
data?
Because types smaller than int are automtically promoted to int for all calculations and you have to cast down to assign anything to them. This leads to cluttered code and quite a lot of confustion (especially when autoboxing is involved).
AvoidUsingShortType: Do not use the short type
List item
short is 16 bit, 2's compliment in java
a short mathmatical operaion with anything in the Integer family outside of another short will require a runtime sign extension conversion to the larger size. operating against a floating point requires sign extension and a non-trivial conversion to IEEE-754.
can't find proof, but with a 32 bit or 64 bit register, you're no longer saving on 'processor instructions' at the bytecode level. You're parking a compact car in a a semi-trailer's parking spot as far as the processor register is concerned.
If your are optimizing your project at the byte code level, wow. just wow. ;P
I agree on the design side of ignoring this pmd warning, just weigh accurately describing your object with a 'short' versus the incurred performance conversions.
in my opinion, the incurred performance hits are miniscule on most machines. ignore the error.
What advantages does block-level
synchronization have over method-level
synchronization?
Synchronize a method is like do a synchronize(getClass()) block, and blocks all the class.
Maybe you don't want that

Categories