In a Java class a method can be defined to be final, to mark that this method may not be overridden:
public class Thingy {
public Thingy() { ... }
public int operationA() {...}
/** this method does #return That and is final. */
public final int getThat() { ...}
}
That's clear, and it may be of some use to protect against accidental overriding, or maybe performance — but that's not my question.
My question is: From an OOP point of view I understood that, by defining a method final the class designer promises this method will always work as described, or implied. But often this may be outside the influence of the class author, if what the method is doing is more complicated then just delivering a property.
The syntactic constraint is clear to me, but what is the implication in the OOP sense? Is final used correctly in this sense by most class authors?
What kind of "contract" does a final method promise?
As mentioned, final is used with a Java method to mark that the method can't be overridden (for object scope) or hidden (for static). This allows the original developer to create functionality that cannot be changed by subclasses, and that is all the guarantee it provides.
This means that if the method relies on other customizable components like non-public fields/methods the functionality of the final method may still be customizable. This is good though as (with polymorphism) it allows for partial customization.
There are a number of reasons to prevent something from being customizable, including:
Performance -- Some compilers can analyse and optimise the operation, especially the one without side-effects.
Obtain encapsulated data -- look at immutable Objects where their attributes are set at the construction time and should never be changed. Or a calculated value derived from those attributes. A good example is the Java String class.
Reliability and Contract -- Objects are composed of primitives (int, char, double, etc.) and/or other Objects. Not all operations applicable to those components should be applicable or even logical when they are used in the bigger Object. Methods with the final modifier can be used to ensure that. The Counter class is a good example.
public class Counter {
private int counter = 0;
public final int count() {
return counter++;
}
public final int reset() {
return (counter = 0);
}
}
If the public final int count() method is not final, we can do something like this:
Counter c = new Counter() {
public int count() {
super.count();
return super.count();
}
}
c.count(); // now count 2
Or something like this:
Counter c = new Counter() {
public int count() {
int lastCount = 0;
for (int i = super.count(); --i >= 0; ) {
lastCount = super.count();
}
return lastCount;
}
}
c.count(); // Now double count
What kind of "contract" does a final method promise?
Look at it the other way, any non final method makes the implicit guarantee that you can override it with your own implementation and the class will still work as expected. When you can't guarantee that your class supports overwriting a method you should make it final.
First of all, you can mark non-abstract classes final as well as fields and methods. This way whole class can't be subclassed. So, behavior of class will be fixed.
I agree that marking methods final don't guarantee that their behavior will be the same in subclasses if these methods are calling non-final methods. If behavior is indeed need to be fixed, this has to be achieved by convention and careful design. And don't forget to notion this in javadoc!(java documentation)
Last but not the least, final keyword has very important role in Java Memory Model (JMM). It's guaranteed by JMM that to achieve visibility of final fields you don't need proper synchronization. E.g.:
class A implements Runnable {
final String caption = "Some caption";
void run() {
// no need to synchronize here to see proper value of final field..
System.out.println(caption);
}
}
I'm not sure you can make any assertions about the use of "final" and how that impacts the overall design contract of the software. You are guaranteed that no developer can override this method and void its contract that way. But on the other hand, the final method may rely on class or instance variables whose values are set by subclasses, and can call other class methods that are overridden. So final is at most a very weak guarantee.
No, it's not outside the influence of the class author. You can't override it in your derived class, therefore it will do what the base class author intended.
http://download.oracle.com/javase/tutorial/java/IandI/final.html
Worth noting is the part where it suggests that methods called from constructors should be final.
Related
I have two Classes like this:
#Data
#NoArgsConstructor
#AllArgsConstructor
public class FooCounts {
private Long countOfRows;
}
#Data
#NoArgsConstructor
#AllArgsConstructor
public class DooCounts {
private Long countOfRows;
}
I created two Lists of the above types and did the following:
List<FooCounts> fooCounts = ...; //initialisation doesn't matter
List<DooCounts> dooCounts = ...;
Long countOfRows = 0L;
if(!fooCounts.isEmpty){
countOfRows = fooCounts.map(FooCounts::getCountOfRows).sum().longValue();
}
if(!dooCounts.isEmpty){
countOfRows = dooCounts.map(DooCounts::getCountOfRows).sum().longValue();
}
Is it possible to make these two 'if' blocks as one 'if' block by creating a method out of it? I mean something like this:
private Long fooDooCounts(List<T> fooDooCounts) {
if(!fooDooCounts.isEmpty){
countOfRows = fooDooCounts.map(fooDooCounts::getCountOfRows).sum().longValue();
}
Java is strictly namespaced. The name of a method/field are relevant only insofar as that they exist in the context of a type (hence, in java you can't define fields or methods outside of a type - because names do not mean anything outside of them), and the name of a type is only meaningful in light of the package it is in.
In other words, the actual name of string's toLowerCase method is java.lang.String::toLowerCase.
There is no way in java to say 'I want to call the toLowerCase method on this object, whatever the type of the object is, regardless of where the method comes from. Long as it is called toLowerCase, call it'. It just doesn't exist. You can see this in action in class files, where any invocation is necessarily always bound up with a fully qualified name (it would look like java/lang/String toLowerCase()Ljava/lang/String; in classfile-ese, but it's the same principle, just in classfile form).
There's a good reason for this.
Imagine these two types:
interface Gun {
void shoot(Person p);
}
interface Camera {
void shoot(Person p);
}
hopefully this illustrates the subtle but serious dangers of allowing you to write, in a programming language 'just call shoot(p) on this object, whatever it might be, if it has a shoot method, go for it'.
Hence, 'can you write code in java that fetches a field of a given name, regardless of what type the objects are, as long as it has a field of some name, just get the data out of it' - the answer is a very very simple: No, you can't, and you don't want to - that is not how java is designed to work, and going against the 'grain' of how a language wants to be used results in all sorts of maintenance headaches.
Fortunately, it also gives you the strategy to fix the problem: Ensure that the 'fetch operation' is the same fully qualified name. How do we do that? By introducing a type that unifies the definition of what countOfRows means, and then have your various classes implement it:
interface RowCounter {
long countRows();
}
Now we have a uniform definition. You can stick docs on this if you want. Then it is simply a matter of implementing it in your types:
class FooCount implements RowCounter {
#Override public long countRows() {
return countOfRows;
}
}
Because now the countRows method in your FooCount class is in fact just a more specific implementation of RowCounter::countRows, the fully qualified name of that method is com.pkg.RowCounter::countRows. Thus, you can now invoke it:
long sum(List<? extends RowCounter> rowCounters) {
long totalCount = 0;
for (var r : rowCounters) totalCount += rowCounters.countRows();
return totalCount;
}
and you can pass a list of FooCounter objects, or a list of BarCounter, or a list of RowCounter, etc.
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 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.
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.
I've recently discovered an interesting way to create a new instance of an object in Google Guava and Project Lombok: Hide a constructor behind a static creator method. This means that instead of doing new HashBiMap(), you do HashBiMap.create().
My question is why? What advantage do you have of hiding the constructor? To me I see absolutely no advantage of doing this, and it seems to break basic object creation principles. Since the beggining you create an object with new Object(), not some Object.createMe() method. This almost seems like creating a method for the sake of creating a method.
What do you gain from doing this?
There are a number of reasons why you might prefer a static factory method instead of a public constructor. You can read Item 1 in Effective Java, Second Edition for a longer discussion.
It allows the type of the object returned by the method to be different than the type of the class that contains the method. In fact, the type returned can depend on the parameters. For example, EnumSet.of(E) will return a different type if the emum type has very few elements vs if the enum type has many elements (Edit: in this particular case, improving performance for the common case where the enum doesn't have many elements)
It allows caching. For instance, Integer.valueOf(x) will, by default, return the same object instance if called multiple times with the same value x, if x is between -128 and 127.
It allows you to have named constructors (which can be useful if your class needs many constructors). See, for example, the methods in java.util.concurrent.Executors.
It allows you to create an API that is conceptually simple but actually very powerful. For instance, the static methods in Collections hides many types. Instead of having a Collections class with many static methods, they could have created many public classes, but that would have been harder for someone new to the language to understand or remember.
For generic types, it can limit how much typing you need to do. For example, instead of typing List<String> strings = new ArrayList<String>() in Guava you can do List<String> strings = Lists.newArrayList() (the newArrayList method is a generic method, and the type of the generic type is inferred).
For HashBiMap, the last reason is the most likely.
This is usually done because the class actually instantiated by the create() method might be different than the type upon which you are invoking the method. i.e. a factory pattern where the create() method returns a specific subclass that is appropriate given the current context. (For example, returning one instance when the currrent environment is Windows, and another when it is Linux).
Unlike constructors, static methods can have method names. Here's a recent class I wrote where this was useful:
/**
* A number range that can be min-constrained, max-constrained,
* both-constrained or unconstrained.
*/
public class Range {
private final long min;
private final long max;
private final boolean hasMin;
private final boolean hasMax;
private Range(long min, long max, boolean hasMin, boolean hasMax) {
// ... (private constructor that just assigns attributes)
}
// Static factory methods
public static Range atLeast (long min) {
return new Range(min, 0, true, false);
}
public static Range atMost (long max) {
return new Range(0, max, false, true);
}
public static Range between (long min, long max) {
return new Range(min, max, true, true);
}
public static Range unconstrained () {
return new Range (0, 0, false, false);
}
}
You couldn't do this using just constructors, as atLeast and atMost would have the exact same signature (they both take one long).
This is called a Factory method pattern. Where the factory lies within the class itself. Wikipedia describes it pretty well but here are a few snippets.
Factory methods are common in toolkits and frameworks where library code needs to create objects of types which may be subclassed by applications using the framework.
Parallel class hierarchies often require objects from one hierarchy to be able to create appropriate objects from another.
Well it would be possible for SomeClass.create() to pull an instance from a cache. new SomeClass() won't do that without some shenanigans.
It would be also be possible for create() to return any number of implementations of SomeClass. Basically, a Factory type of dealio.
Although not applicable to this particular code example, the practice of hiding the constructor behind a static method is Singleton Pattern. This is used when you want to ensure that a single instance of the class is created and used throughout.
There are many reasons to use this factory method pattern, but one major reason Guava uses it is that it lets you avoid using type parameters twice when creating a new instance. Compare:
HashBiMap<Foo, Bar> bimap = new HashBiMap<Foo, Bar>();
HashBiMap<Foo, Bar> bimap = HashBiMap.create();
Guava also makes good use of the fact that factory methods can have useful names, unlike constructors. Consider ImmutableList.of, ImmutableList.copyOf, Lists.newArrayListWithExpectedSize, etc.
It also takes advantage of the fact that factory methods don't necessarily have to create a new object. For instance, ImmutableList.copyOf, when given an argument that is itself an ImmutableList, will just return that argument rather than doing any actual copying.
Finally, ImmutableList's factory methods return (non-public) subclasses of ImmutableList such as EmptyImmutableList, SingletonImmutableList and RegularImmutableList depending on the arguments.
None of these things are possible with constructors.
i got very interesting reason to hide constructor check it and please let me know if there is any other alternative to achieve this
enter code here
Class A
{
String val;
protected A( )
{
}
protected A(String val)
{
this.val=val;
}
protected void setVal( String val)
{
this.val=val;
}
public String getVal()
{
return val;
}
}
class B extends A
{
B()
{
super();
}
public val setVal(String val)
{
super.val=val;
}
}
class C extends A
{
C(String val)
{
super(val);
}
}
Some main reasons
Primarily it gives you the power to instantiate a different (sub) class
Possibility to return null
It enables you to return an already existing object