I was wondering what the difference is between
public final type attribute_name;
and
private type attribute_name;
public type getA_name() {
return attribute_name;
}
Basically I want to make an attribute read-only, so it can't change after it has been initialized.
Do I make it public final, or do I make it private, and only make it accesible through a get method (without a set method)?
When it's not final but private, the class itself is able to change the value.
A final field MUST be set before the constructor exits. Once set, the reference cannot be modified (the value cannot be reassigned). Emphasis on the cannot be reassigned. This means that while the reference cannot change, the value itself can change.
This is legal:
final List<Integer> list = new List<Integer>();
list.add(5); // the value of list changes, but the reference doesn't
This is not:
final List<Integer> list = new List<Integer>();
list = new List<Integer>(); // may seem sort of redundant but the compiler won't allow it nonetheless
A private variable with a only getter can be reassigned internally by the class that holds it (but it's not visible externally so it cannot be reassigned outside the class holding it). Also, outside the class the reference is inaccessible so the variable cannot be modified except by the class holding it.
A final variable cannot be reassigned anywhere, but if it's public, another class can still access the reference and change the value of whatever object it points to.
If you don't want the variable to be reassigned after initialization as you described, use both final and private.
Use final for something like this:
public class User {
private final long registrationTimeMillis;
public User(/* various parameters probably would be here */) {
registrationTimeMillis = System.currentTimeMillis();
}
public long getRegistrationTimeMillis() {
return registrationTimeMillis;
}
}
We don't expect that a user's registration time will change, so it makes sense to not allow it to change after construction.
Use private with no setter for something like this:
public class VendingController() {
private int drinksStocked = 0;
private int drinksDispensed = 0;
public void dispenseDrink() {
drinksDispensed++;
}
public void stockDrinks(int numberOfDrinks) {
drinksStocked = getDrinksRemaining() + numberOfDrinks;
drinksDispensed = 0;
}
public int getDrinksRemaining() {
return drinksStocked - drinksDispensed;
}
}
We don't want the value of drinksDispensed to change except when dispenseDrink() or stockDrinks(int numberOfDrinks) is called. It still needs to be able to be reassigned by it's own class when the vending machine is refilled though, so we shouldn't make it final
With respect to using public final, generally in Java that's only done for constants and that static keyword is also included since constants shouldn't be dependent on an instance.
An example of when it makes sense to use public static final
public class UnitConversions {
public static final double CENTIMETERS_PER_INCH = 2.54;
}
It could then be used in a method as follows
public double convertFromCentimetersToInches(double centimeters) {
return centimeters / UnitConversions.CENTIMETERS_PER_INCH;
}
Best of luck OP and happy coding.
More reading on final fields
This depends on some factors.
If this is a real constant that is known before and will never change, then use final. In Java final fields can be initialized in the constructor as well, so if your value is known at construction time then you can use final too.
If this value gets set (once, multiple times) during runtime then use private + getter.
The final modifier allows a field to be assigned only once - it cannot be changed after that and it has to be set at during object construction (that is, before the constructor returns).
If you want to make the field read-only, use the principles of information hiding: make it private and provide a public getter that returns the field (or a copy of it for non-primitive types).
You should use public final only for true constants. Even if your field is immutable because of final it is often a good idea to still make it private.
The correct way is to think in the future. What would help you achieve your goals? Maybe later you would also like to give that variable a value. If I were you, I'd do this by creatin a get method and keeping the variable private.
Full documentation for final keyword : http://en.wikipedia.org/wiki/Final_(Java)
Depends on where you want to access it from. Public variables can be accessed from any class within the project and package where private can only be accessed from the class where the variable is.
The 'final' operator makes it permanent and read-only.
Let's assume that type is a reference to an object, not a primitive type.
public final type attribute_name means that attribute_name cannot be reassigned to refer to something else. But attribute_name can be used to call a method that changes its state.
In private type attribute_name, only methods within the class can call methods on attribute_name.
So if you want it to remain constant, use approach (2). Limit the public methods to ones that ultimately call methods on attribute_name that don't modify its state.
Related
I often define variables as class/instance variables ('global' before edit, thanks for the clarification) in my class while programming in Android. In case I need to access it later, say in another method after it's been assigned in onCreate().
For the occasions where I don't actually access them later, Android Studio's Lint code inspection throws warnings stating that the "Field can be converted to a local variable".
I know I will get the same functionality either way, but is there any performance or security benefit to inline/local method variables in Java (specifically on Android, but also in general) vs. declaring them as private class/instance variables within a class?
EDIT/CLARIFICATION: By 'global', I meant in the scope of the class. (What I know understand to be referred to as 'class' or 'instance' variables, my bad) Accessible by all methods within the class and not an inline or method specific variable. Maybe a sort of example code will illustrate my point. EX:
public class MyActivity {
//Android Studio Lint will throw Java Class structure 'Field can be local' warnings
//which is why I'm referring to these variables as "global"
private SomeDataType myPrivateVariable1; //'Field can be converted to a local variable'
public SomeDataType myPublicVariable1; //'Field can be converted to a local variable'
private SomeDataType myPrivateVariable2;
public SomeDataType myPublicVariable2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_layout);
//assign data to variables from either intent bundle or preferences or w/e
myPrivateVariable1 = SOME_DATA;
myPublicVariable1 = SOME_DATA;
//AS will suggest change to:
// SomeDataType myPrivateVariable1 = SOME_DATA;
// SomeDataType myPublicVariable1 = SOME_DATA;
myPrivateVariable2 = SOME_DATA;
myPublicVariable2 = SOME_DATA;
//AS Lint will throw warning that variables can be converted b/c only used here
someMethod(myPrivateVariable1);
someOtherMethod(myPublicVariable1);
//run a method that uses the variables
myMethodUsingVariable2(input);
}
private void myMethodUsingVariable2(DataType input) {
//access the variables in multiple methods will not trigger the warning
if (input == something) {
//do something with 'myPrivateVariable2' and 'myPublicVariable2'
}
}
}
What is the performance benefit to this? If later I find I need to use either myPrivateVariable1 or myPublicVariable1 in another method as I add a feature or change something, it would be easier to write new methods that used the data if they were already saved to a defined class variable and assigned a value from the onCreate() method. Is the only benefit memory allocation that will only significantly affect performance if the variables are large data sets? What would be the difference between public and private in that regards as well?
I often define variables as global (private) in my class while
programming in Android. In case I need to access it later, say in
another method after it's been assigned in onCreate().
What you meant is a term for Class Scope variable.
I know I will get the same functionality either way, but is there any
performance or security benefit to inline/local method variables in
Java (specifically on Android, but also in general) vs. declaring them
as private global variables within a class?
The major benefit using a method scope variable is maintainability. Consider the following class with class scope variable:
public class SampleClass {
// a class scope variable
private int mHeight;
private int getSquareValueOfHeight() {
return mHeight * mHeight;
}
private void increaseHeightByOne() {
mHeight = mHeight + 1;
}
}
we have two method; getSquareValueOfHeight() which read the value of mHeight and return the square value of it, and increaseHeightByOne() which modified the value of mHeight.
You can see that you need to check mHeight whenever you need to change both the methods. How about if there are 3 or 5 or more methods accessing the mHeight? You have to recheck of all the methods just to make sure a change doesn't break your whole code.
Now consider the following class:
public class SampleClass {
private int height;
private int getSquareValueOfHeight(int value) {
int height = value * value;
return;
}
private int increaseHeightByOne(int height) {
return height + 1;
}
}
we have two methods that using a value from its parameter. The getSquareValueOfHeight() will return a squared value without modifying the class scope height variable because it has its own height variable (this is a shadowing mechanism). When you're calling the following code:
SampleClass sampleClass = new SampleClass();
int value = sampleClass.getSquareValueOfHeight(5);
the class scope variable height won't be changed. So, you don't need to worry that a change will broke your whole code.
I'm developing a LALG compiler to my college course on Java 1.6. So I did a types class and grammar class.
EnumTypes
public enum EnumTypes {
A("OLA"),
B("MUNDO"),
C("HELLO"),
D("WORLD"),
/**
* The order below is reversed on purpose.
* Revert it and will you get a NULL list of types furder.
*/
I(EnumGrammar.THREE),
H(EnumGrammar.TWO),
F(EnumGrammar.ONE),
E(EnumGrammar.ZERO);
private String strValue;
private EnumGrammar enumGrammarValue;
private EnumTypes(String strValue) {
this.strValue = strValue;
}
private EnumTypes(EnumGrammar enumGrammarValue) {
this.enumGrammarValue = enumGrammarValue;
}
public String getStrValue() {
return strValue;
}
public EnumGrammar getEnumTiposValue() {
return enumGrammarValue;
}
}
EnumGrammar
public enum EnumGrammar {
ZERO(EnumTypes.A,EnumTypes.B,EnumTypes.F,EnumTypes.D),
ONE(EnumTypes.C),
TWO(EnumTypes.B,EnumTypes.H),
THREE(EnumTypes.D,EnumTypes.A,EnumTypes.C);
private EnumTypes[] values;
private EnumGrammar(EnumTypes ... values) {
this.values = values;
}
public EnumTypes[] getValues() {
return values;
}
}
When I call EnumTypes.E.getEnumTiposValue().getValues() where are supposed to be the EnumTypes.F value is NULL.
Main
public class Main {
public static void main(String[] args) {
//prints [A, B, null, D]
System.out.println(Arrays.toString(EnumTypes.E.getEnumTiposValue().getValues()));
}
}
There are a workaround or something like that?
Thanks!
Essentially, it is always a very risky thing to allow a reference to an object to get outside of the class before the class is fully constructed, that is before the constructor is finished. Enums are singletons. Here you have two classes whose constructors receive each other's instances in a circular dependency. Add to this that class loading is lazy, so the classes will be loaded and enum instances created as you go and it sounds quite reasonable that the ends result depends on the order in which the enums are initialized.
I can't quote the corresponding point from JLS right now (I'll look for it), but I believe that if you allow a reference to an object to "leave the class" from outside of the constructor (which happens here due to enums being singletons initialized by the JVM), the JVM is free to do something strange.
EDIT: these points from the JLS are of importance for the case:
17.5.2 - A read of a final field of an object within the thread that constructs that object is ordered with respect to the initialization of that field within the constructor by the usual happens-before rules. If the read occurs after the field is set in the constructor, it sees the value the final field is assigned, otherwise it sees the default value. Since enum values are internally treated like static final fields (see 16.5 below), if you reference one enum from inside the constructor of another enum whose constructor references the first one, at least one of these two objects will not yet have been fully initialized and so the reference may still be null at this point.
16.5 - The definite assignment/unassignment status of any construct within the class body of an enum constant is governed by the usual rules for classes
8.3.2 - rules for initialization of fields
12.4.1 - when initialization occurs
Here is what's happening, in order:
Your code calls EnumTypes.E.getEnumTiposValue(), triggering class loading of EnumTypes.
Static initialization of EnumTypes begins - its enum constants will be initialized in the order they're declared.
EnumTypes.A through EnumTypes.D are initialized.
EnumTypes.I begins initialization - its constructor call references EnumGrammar.THREE, triggering class loading of EnumGrammar.
Static initialization of EnumGrammar begins - its enum constants will be initialized in the order they're declared.
EnumGrammar.ZERO is initialized - its constructor call references EnumTypes.A, EnumTypes.B, EnumTypes.F, and EnumTypes.D. Out of those, EnumTypes.F has not yet been initialized. Therefore, the reference to it is null.
From there, static initialization of the two enum classes finishes, but it doesn't matter for EnumGrammar.ZERO - its values field has already been set.
For the workaround, suppose that you have EnumA and EnumB, I will just put EnumB's name in EnumA's constructor.
When you have to retrieve EnumB from EnumA, you can simply use EnumB.valueOf(EnumA.this.enumB)
For example, Question is the EnumB
public enum Question {
RICH_ENOUGH(R.string.question_rich_enough, Arrays.asList(Answer.RICH_ENOUGH_YES, Answer.RICH_ENOUGH_NO)),
ARE_YOU_SURE(R.string.question_are_you_sure, Arrays.asList(Answer.ARE_YOU_SURE_YES, Answer.ARE_YOU_SURE_NO)),
FOUND_A_NEW_JOB(R.string.question_found_new_job, Arrays.asList(Answer.FOUND_A_NEW_JOB_YES, Answer.FOUND_A_NEW_JOB_NO)),
// ...
and Answer is the EnumA
public enum Answer {
RICH_ENOUGH_YES(R.string.answer_yes, "ARE_YOU_SURE"),
RICH_ENOUGH_NO(R.string.answer_no, "THAT_SOMEBODY"),
ARE_YOU_SURE_YES(R.string.answer_yes, null),
ARE_YOU_SURE_NO(R.string.answer_no, "FOUND_A_NEW_JOB"),
FOUND_A_NEW_JOB_YES(R.string.answer_yes, "GO_FOR_NEW_JOB"),
// ...
private final int answerStringRes;
// Circular reference makes nulls
private final String nextQuestionName;
Answer(#StringRes int answerStringRes, String nexQuestionName) {
this.answerStringRes = answerStringRes;
this.nextQuestionName = nexQuestionName;
}
Whenever I need to get the next Question from an Answer
public Question getNextQuestion() {
if (nextQuestionName == null) {
return null;
}
return Question.valueOf(nextQuestionName);
}
This should be simple enough to be a workaround.
Example source: an open source Android app for fun I just written last night - Should I Resign?
I know what this does and why it's useful - this question did a great job of explaining it. However, in the chosen answer they used this to also assign parameters. Does doing
private int aNumber;
public void assignVal(int aNumber){
this.aNumber = aNumber;
}
have any advantage over this?
private int aNumber;
public void assignVal(int aVal){
aNumber = aVal;
}
There is no performance or other obvious advantage for using this.aNumber vs. just aNumber, other than possibly clarity of to which object instance the aNumber belongs. Basically it comes down to preference.
When using just aNumber, the this prefix is implied.
One possible advantage and a case where using the this becomes necessary is when you have a method that has an argument passed to the method that has the exact same name as a class instance variable. In this case, it is necessary to prefix the class instance variable with this to 'choose' the right property to access.
For example, if you have a class and method declared as:
class ThisExample{
private int aNumber;
public void setANumber(int aNumber){
//Here is is necessary to prefix with 'this' to clarify
//access to the class instance property 'aNumber'
this.aNumber = aNumber;
}
}
It means that you don't have to figure out 2 variable names that refer to one thing. It is slightly more readable, and makes it so your variables are always descriptive of the value.
I have a dilemma because I don't know what is better solution. I have a static variable.
I wonder what is the best practice of declaring these variables.
Let's suppose that I have such a variable in myStatic class.
public class myStatic(){
public static int integer = 0;
/* get value */
public int getInteger() {
return integer;
}
/* set value */
public void setInteger(int nInteger) {
integer = nInteger;
}
}
Now I must increment this variables or decrements.
How to do it correctly?
1)
myStatic.integer++;
2)
myStatic mystatic = new myStatic();
int integer = mystatic.getInteger();
int nInteger = integer+1;
mystatic.setInteger(iInteger);
Is better using solution 1 or 2?
I would go with number 1, 100%, maybe just because I'm lazy, but kind of also because of:
Don't repeat yourself
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Keep it simple, stupid
This principle has been a key, and a huge success in my years of software engineering. A common problem among software engineers and developers today is that they tend to over complicate problems.
You aren't gonna need it
Principle of extreme programming (XP) that states a programmer should not add functionality until deemed necessary.
If that variable needs to be accessed everywhere and at any time, you should go with option 1.
It will act as an Environment variable even tho its not reallyyyy the same thing.
more info on env vars:
https://en.wikipedia.org/wiki/Environment_variable
Static variables need not be accessed through an object. Infact it is a waste of code.
Consider this :
public class MyStatic {
public static int i = 0;
}
You can directly access the static variable like this :
private MyStatic myStatic = null;
myStatic.i++;
This is because, the JVM doesn't even care about the object for a static property.
since static vars are class variables, they can be manipulated by any object, unless you declare a static variable as private, you had to access to it via public static methods. Then, your first approach is correct, in the second the method getInteger() does not work.
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
I recomend you to read about the singleton pattern design.
I've been using PMD to help spot potential problems in my Java code, and I've been finding its advice to be split between the useful, the idiosyncratic, and the "WTF?!".
One of the things it keeps telling me to do is to use the final keyword for literally every variable I can attach it to, including input parameters. For actual constants this seems sensible, but for other stuff it just strikes me as odd, possibly even a tad counterproductive.
Are there concrete advantages/disadvantages to hanging final on every variable declaration you possibly can?
"Every variable declaration you possibly can" sounds a bit extreme, but final is actually beneficial in many ways. Sometimes I wish that final was the default behavior, and required no keyword, but true "variables" required a variable modifier. Scala adopted something like this approach with its val and var keywords—using val (the final-like keyword) is strongly encouraged.
It is especially important to carefully consider whether each member variable is final, volatile, or neither, because the thread safety of the class depends on getting this right. Values assigned to final and volatile variables are always visible to other threads, without using a synchronized block.
For local variables, it's not as critical, but using final can help you reason about your code more clearly and avoid some mistakes. If you don't expect a value to change within a method, say so with final, and let the compiler find unnoticed violations of this expectation. I'm not aware of any that do currently, but it's easily conceivable that a JIT compiler could use this hint to improve performance too.
In practice, I don't declare local variables final whenever I could. I don't like the visual clutter and it seems cumbersome. But, that doesn't mean it's not something I should do.
A proposal has been made to add the var keyword to Java aimed at supporting type inference. But as part of that proposal, there have been a number of suggestions for additional ways of specifying local variable immutability. For example, one suggestion was to also add the key word val to declare an immutable variable with inferred type. Alternatively, some advocate using final and var together.
final tells the reader that the value or reference assigned first is the same at any time later.
As everything that CAN be final IS final in this scenario, a missing final tells the reader that the value will change later, and to take that into account.
This is a common idiom for tools like PMD. For example, below are the corresponding rules in Checkstyle. It's really a matter of style/preference and you could argue for both sides.
In my opinion, using final for method parameters and local variables (when applicable) is good style. The "design for extension" idiom is debatable.
http://checkstyle.sourceforge.net/config_misc.html#FinalParameters
http://checkstyle.sourceforge.net/config_design.html#DesignForExtension
http://checkstyle.sourceforge.net/config_coding.html#FinalLocalVariable
PMD also has option rules you can turn on that complains about final; it's an arbitrary rule.
If I'm doing a project where the API is being exported to another team - or to the world - leave the PMD rule as it stands. If you're just developing something that will forever and always be a closed API, disable the rule and save yourself some time.
Here are some reason why it may be beneficial to have almost everything tagged as final
Final Constants
public static class CircleToolsBetter {
public final static double PI = 3.141;
public double getCircleArea(final double radius) {
return (Math.pow(radius, 2) * PI);
}
}
This can be used then for other parts of your codes or accessed by other classes, that way if you would ever change the value you wouldn't have to change them one by one.
Final Variables
public static String someMethod(final String environmentKey) {
final String key = "env." + environmentKey;
System.out.println("Key is: " + key);
return (System.getProperty(key));
}
}
In this class, you build a scoped final variable that adds a prefix to the parameter environmentKey. In this case, the final variable is final only within the execution scope, which is different at each execution of the method. Each time the method is entered, the final is reconstructed. As soon as it is constructed, it cannot be changed during the scope of the method execution. This allows you to fix a variable in a method for the duration of the method. see below:
public class FinalVariables {
public final static void main(final String[] args) {
System.out.println("Note how the key variable is changed.");
someMethod("JAVA_HOME");
someMethod("ANT_HOME");
}
}
Final Constants
public double equation2Better(final double inputValue) {
final double K = 1.414;
final double X = 45.0;
double result = (((Math.pow(inputValue, 3.0d) * K) + X) * M);
double powInputValue = 0;
if (result > 360) {
powInputValue = X * Math.sin(result);
} else {
inputValue = K * Math.sin(result); // <= Compiler error
}
These are especially useful when you have really long lines of codes, and it will generate compiler error so you don't run into logic/business error when someone accidentally changes variables that shouldn't be changed.
Final Collections
The different case when we are talking about Collections, you need to set them as an unmodifiable.
public final static Set VALID_COLORS;
static {
Set temp = new HashSet( );
temp.add(Color.red);
temp.add(Color.orange);
temp.add(Color.yellow);
temp.add(Color.green);
temp.add(Color.blue);
temp.add(Color.decode("#4B0082")); // indigo
temp.add(Color.decode("#8A2BE2")); // violet
VALID_COLORS = Collections.unmodifiableSet(temp);
}
otherwise, if you don't set it as unmodifiable:
Set colors = Rainbow.VALID_COLORS;
colors.add(Color.black); // <= logic error but allowed by compiler
Final Classes and Final Methods cannot be extended or overwritten respectively.
EDIT: TO ADDRESS THE FINAL CLASS PROBLEM REGARDING ENCAPSULATION:
There are two ways to make a class final. The first is to use the keyword final in the class declaration:
public final class SomeClass {
// . . . Class contents
}
The second way to make a class final is to declare all of its constructors as private:
public class SomeClass {
public final static SOME_INSTANCE = new SomeClass(5);
private SomeClass(final int value) {
}
Marking it final saves you the trouble if finding out that it is actual a final, to demonstrate look at this Test class. looks public at first glance.
public class Test{
private Test(Class beanClass, Class stopClass, int flags)
throws Exception{
// . . . snip . . .
}
}
Unfortunately, since the only constructor of the class is private, it is impossible to extend this class. In the case of the Test class, there is no reason that the class should be final. The test class is a good example of how implicit final classes can cause problems.
So you should mark it final when you implicitly make a class final by making its constructor private.