I'm adapting a simulation written in Java. My limited background is all in C++.
The current implementation of the simulation relies on a class called Parameters. An instance of class Simulation references attributes of Parameters, which I don't think is ever instantiated. The Parameters class has a structure like
public class Parameters {
public static int day = 0;
public static final int endDay = 365;
....
public static int getDate() {
return day;
}
}
In an instance of Simulation, there are references to, e.g., Parameters.day.
Currently, all the attributes of Parameters are hard-coded. I need to be able to change some of them with command-line arguments. For example, I'd like to be able to set a different endDay using a Parameters::setEndDay(int customDay) sort of function.
My first thought was to create an instance (Parameters parameters = new Parameters()) and completely rewrite the Parameters class so that all its attributes are private and only accessible through accessor functions. I'm concerned that this approach is not very efficient. Thus far, I have tried a hybrid approach in which I create an instance of the Parameters class, which I then pass to an instance of Simulation while still occasionally referencing Parameters.day (something I don't need to change).
One of the problems is that I don't have a good sense of class privileges in Java.
Suggestions appreciated.
If you make all of them non-final, then you can just set them directly from your command-line arguments before instantiating the Simulation class:
// read command-line arguments
Parameters.endDay = 123; // this will change all reference to Parameters.endDay
new Simulation(...)
create static method setEndDay(int customDay) in Parameters class. And you can change value without accesing with class not object: Parameter.setEndDay(10). Note that endDay variable should be non final.
Accessing static member variables vs instantiating an object
Essentially this is a choice between global data or local data. A class variable (keyword static) exist in one place for your entire application. E.g. you cannot have two parametrizations running simultaneously in the same application (although you can run two applications in parallell or sequentially). Using instantiated objects you can have several Parameter objects containing different values.
Accessor methods vs accessible member variables
There are some controversy around this. Schoolbooks usually state that all data should be encapsulated using accessor methods to protect the objects internal state. It is however as you state slightly less efficient and there are cases where making member variables directly accessible is considered good practice.
Java Access Modifiers
Java supports four different access modifiers for methods and member variables.
Private. Only accessible from within the class itself.
Protected. Can be accessed from the same package and a subclass existing in any package.
Default (no keyword). Only accessible by classes from the same package.
Public. Accessible from all classes.
Related
In Java, a static method is used to save memory because there is no need to create an object to call static methods. And we need to create an object when we have to call instance methods; so whenever we create an object it takes memory. We know that, in any project, maximum methods are non-static.
Why then do we not declare all methods as static, instead of having instance methods be the norm, in order to save memory in a project?
Some methods — probably most — need information in order to do their work. You have to store that information somewhere.
If all of your methods are static, that doesn't magically make the need for that information go away. And if you need the information, you need to store it, so you can pass it into the static method so the method can do its work. So there's no memory savings achieved by using only static methods: You're going to store that information somewhere.
In Java's style of object-oriented programming (and many but not all others), you store that information with (conceptually) the functions that operate on it (instance methods): An object.
For methods that don't need information, or that reasonably should receive all of the information they operate on via parameters, we use static methods.
I'm writing an explanation for some code for a course, and have been accidentally using the words method and function interchangeably. I decided to go back over and fix the wording, but ran into a hole in my understanding.
From what I understand, a subroutine is a function if it doesn't act on an instance of a class (its effect is restricted to its explicit input/output), and is a method if it operates on an instance of a class (it may carry out side effects on the instance that make it impure).
There's a good discussion here on the topic. Note that by the accepted answer's definitions, a static method should actually be a function because an instance is never implicitly passed, and it doesn't have access to any instance's members.
With this is mind though, shouldn't static methods actually be functions?
By their definition they don't act on particular instances of a class; they're only "tied" to the class because of relation. I've seen a few good looking sites that refer to static subroutines as "methods" though (Oracle, Fredosaurus, ProgrammingSimplified), so either they're all overlooking the terminology, or I'm missing something (my guess is the latter).
I'd like to make sure I am using the correct wording.
Can anybody clear this up?
This quote from 8.4.3.2 may help:
A method that is declared static is called a class method.
A method that is not declared static is called an instance method [...].
Class methods: associated with a class.
Instance methods: associated with an instance.
Java just wants you to "think object-oriented". Also, static methods have access to a surrounding scope which may include state. In a way, the class is like an object itself.
The simple answer is that when Java decided to call everything a "method", they didn't care about the distinction between a function and a method in theoretical computer science.
Static methods are not exactly functions, the difference is subtle, but important.
A static method using only given input parameters is essentially a function.
But static methods may access static variables and other static functions (also using static variables) so static methods may have a state which is fundamentally different to a function which are by definition stateless.
(ADDENDUM: While programmers are often not so strict with using "function" as definition, a strict function in computer science can access only input parameters). So defining this case of accessing static fields it is not valid to say that static methods are always functions.
Another difference which justifies the usage of "static method" is that you can define in C derivates global functions and global variables which can be accessed everywhere. If you cannot access the class which contain static methods, the methods are inaccessible, too. So "static methods" are limited in their scope by design in contrast to global functions.
In Java, a user-defined class is actually an instance of a subclass of java.lang.Class.
In this sense, static methods are attached to an instance of a conceptual class: they are attached to an instance of a subclass of java.lang.Class.
With this in mind, the term "class method" (an alternate name for Java's static methods) begins to make sense. And the term "class method" can be found in many places: Objective C, Smalltalk, and the JLS -- to name just a few.
In computer science function clearly maps to a static method. But "method" of a class is a bit generic, like "member" (field member, method member). There are wordings like
Data members and method members have two separate name spaces: .x and .x() can coexist.
So the reason is, that as the philosoph Ludwig Wittgenstein said, Language is a tool with different contexts. "Method" is a nice moniker in the citation above to categorize a "member".
Your thinking is right and it makes sense. It's just not established terminology in the Java community. Let me explain some internals that can help understand why the terminology subsists.
Java is a class based object oriented language. A method is always member of a class or instance (This is a general statement valid for other programming languages too). We think of class and instance being both objects.
Instance method (dynamic)
You cannot invoke this method from a class directly, you have to create an instance. Each instance references that method. You can overwrite a method definition with the exact same method signature (when subclassing), i.e. the reference points to a different method (which has the same signature, but can have a different method body). The method is dynamic.
Class method (static)
You only can invoke this method from the class directly, i.e. you don't need to create an instance of that class. There is only one global definition of that method in the whole program. You cannot overwrite the exact same method signature when the method is declared static, because there is only one definition valid for the whole program. Note that the method is member of the class object itself, the instances have all the same unique (and fix) reference to that method.
Here is another take on the terminology, using Scala as a mnemonic:
In Scala you have objects, which are singleton instances of an implicitly defined class 1.
Per your definition, we can call these subroutines belonging to the object methods, as they operate on a single instance of the class.
Additionally the object will also define class A, and create all of the methods in object A as static methods on class A (for interfacing with Java) [2].
Therefore we can say that the static methods of Java class A access the same members as the Scala singleton instance, which per your definition then deserve to be called (static) methods of class A.
Of course, the main difference is - method can use static fields, not only method parameters.
But there is additional one - polymorphism!
Results of evaluation Class A.doTheSameStaticMethod() and ClassB.doTheSameStaticMehod() will be depends of class. In this case function is impotent.
Each class has an object to represent it that is an instance of a subclass of the Class class. Static methods are really instance methods on these objects that are instances of a subclass of Class. They have access to state in the form of static fields, so they are not restricted to being just (stateless) functions. They are methods.
This question already has answers here:
What does the 'static' keyword do in a class?
(22 answers)
Closed 8 years ago.
I'm quite new to Java and I'm trying to understand static variables and methods. Could someone give me a brief explanation of why I'd use the static method over the instance method and also what would be the ideal situation to use static variables? I know that static variables and methods are part of the class and not an instance of said class but I'm having trouble understanding when I'd use it.
Thanks!
These are the main differences
1.Static variables take memory only 1 time during the lifetime of program.
2.You can call static variables or methods. without creating the object of that class by classname only.
3.Static variables can be called in static and non-static context.
Mainly static variables are used to save memory because every object takes memory .
Static members relate to a type not a concrete instance. So instance methods and variables concern the identity of the instance, e.g. an instance method can alter the state of the object.
To some extend this is a religious question. Some people prefer to create static methods in a class when they do not access any instance variable. Other people do not like this approach. Another usual usage is creating factory methods, able to create an instance of an object while itself being called statically.
Often there are utility classes that contain static methods to serve clients with some functionality that is not bound to any type context. But all too often these utility classes get abused by using them as a trash bin for all sorts of methods a programmer did not find a fitting class for. This may be a result of poor design.
A popular use of static variables is the definition of an logger instance (e.g. SLF4J) for a class because loggers are thread safe and can be used by all instances and static methods alike. One advantage is (see a comparison) that only one instance has to be created for all instances of the containing class.
For static variable or method, you can think of that there is only one copy of the variable or method during the whole life time of the program.
So if you there is variable whose value should be shared across all the processes or thread, you can declare a static variable. For example, when you want to use a singleton pattern, you will need a static variable to indicate if there is instance of the class already.
For static methods, I would use them when state of the class is not important. I think the best example is java.lang.Math, they are all static methods, and returns the expected values to you no matter what you called before.
I know what static is, but just not sure when to use it.
static variable:
I only used it for constant fields. Sometimes there are tens of constants in a class, so using static constants can save lots of memory. Is there any other typical use cases?
static method:
I use it when I make a class about algorithms. For example, a class which provides different sorting algorithms. Is it against OOP design? I think it is better to maintain this way rather than implementing sorting algorithms inside each class that needs to use them. Am I wrong? What are some good use cases?
Also, are there any performance difference between using static and non-static fields/methods?
You are describing cases where you've used static, but this doesn't quite explain fundamentally why you would use static vs non-static - they are more than just keywords for constants and utility methods.
When something is not static (instance), it means that there is an instance of it for each instance of the class. Each one can change independently.
When something is static, it means there is only one copy of it for all instances of the class, so changing it from any location affects all others.
Static variables/methods typically use less memory because there is only one copy of them, regardless of how many instances of the class you have. Statics, when used appropriately, are perfectly fine in object oriented design.
If you have a method/variable that you only need one instance of (e.g. a constant or a utility method), then just make it static. Understand though that making a method static means it cannot be overridden. So if you have a method you want to override in a subclass, then don't make it static.
The general rule of thumb is - if you need only one copy of it, make it static. If you need a copy per instance, then make it non static.
Is there any other typical use cases?
Global Variables
Is it against OOP design?
Not exaclty, the point is that static methods are stateless since you don't need a particular instance of a class. My favorite approach is for utility methods (like Apache Commons). But you may be aware that some methods may be better placed as class members instead of static.
Also static methods can make class testability harder once you can't override these methods or replace by mock implementation.
Performance difference ?
There's a performance Android recommendation from Google that says "prefer static over virtual":
http://developer.android.com/training/articles/perf-tips.html#PreferStatic
I'm not sure it's true for JVM since Android uses a different VM, but it makes sense given the reasons the link points out:
If you don't need to access an object's fields, make your method static. Invocations will be about 15%-20% faster. It's also good practice, because you can tell from the method signature that calling the method can't alter the object's state."
My personal rule of thumb is that static things are "just hanging out there". They are things that (disclaimer, not entirely true) are global, but make sense to include with this one particular class.
Static fields are good if you find yourself loading some heavyweight objects repeatedly. For instance, the project I'm working on now has a toggle between two images. These are static fields that are loaded with the application and kept in memory, rather than reloading them every time and letting GC take care of the mess.
Apart from very specific situations, I use static (and final) variables for constants only. It's a totally valid to use them, of course.
I tend to avoid static utility methods, because they make it harder to write unit tests for the code (mocking the results of the method invocation). When you start developing Test Driven way, this issue becomes quite apparent. I prefer using dependency injection and singleton beans (though it depends on your needs and situation).
Static variables belong to a class, hence shared by all the objects, so memory usage is less if you really want the varible to be shared. If you declare the variable as public and static, then it is globally available for everyone.
Static methods are generally the utility methods, depending on the access modifier, those can be used within a class or across the classes. Static utility class will help to reduce the memory usage again because you need not to create the object to call those methods.
The static field has one value among all objects and they call it Class member also because it's related to the class.
You can use static filed as a utility.
an example just Assume we need to know how many instances we have :
class Counter
public class Counter {
public static int instanceCount ;
public Counter()
{
instanceCount++;
}
public int getInstanceCount()
{
return instanceCount;
}
}
After creating two instances of Counter Class. But they share the same instanceCount field because it's a static field so the value of instanceCount will become the same in firstCounter and secondCounter .
Class main
Counter firstCounter = new Counter();
// will print 1
System.out.println(co.getInstanceCount());
// will print 2
Counter secondCounter = new Counter();
System.out.println(co1.getInstanceCount());
Util class in java can be made in two ways
class Utils
{
public static ReturnType someUtilMethod(
// ...
}
and execute util method by
Utils.someUtilMethod(...);
Or I can make
class Utils
{
public Utils(){}
public ReturnType someUtilMethod(
// ...
}
and execute util method by
new Utils().someUtilMethod(...)
What way is better? Are some differences between this ways?
Generally Util class contains Utility methods which doesn't need to store the state of Object to process and so static methods are good fit there
A utility function should always be static, unless for some reason it depends on the state of some other variables, and those variables need to be remembered between calls.
The latter should almost never happen, although something like a pseudo-random number generator might be a good case.
The Math functions are a good example of utility functions. When you call Math.sin() the result depends only on the supplied parameter. There is no "state" involved, so there's no need to create an object.
static access will be a better approach as in Util class hold methods which are not concerned with the attributes of the Objects.
Another example will be of Math Class.
Math class has no Instance variables.
And has private constructor, so no object can be created.
So in Math class case using static access like Math.PI is appropriate.
If you use a class that only has static methods, you will not need to instantiate the object everytime you need to use it, saving a line of code and some memory. Just remember to make the default constructor private, so that no one cane inadvertently instantiate it!
A utility class is just a place where to syntactically hold global functions in Java.
Your second example is not covered by the term "utility class". The definition of that concept includes non-instantiability of the class.
The reason to have instance methods would be dynamic method dispatch (to achieve polymorphism), or possibly hold some non-global state. But, as I said, then you would be out of the scope of the term "utility class".