Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I got in touch with the functional programming paradigm (haskell, scala) and like the concept. I'm trying to incorporate these functional principles in my every day work.
Here an example
public class Functional
{
private final Object o1;
private final Object o2;
public Functional(Object o1, Object o2)
{
this.o1 = o1;
this.o2 = o2;
}
/*
* method has side effects
*/
private void method()
{
// o1.someChange();
// ...
// o2.someChange();
}
/*
* method has no side effects - it only uses its parameters
*/
private static void method(Object o1, Object o2)
{
// o1.someChange();
// ...
// o2.someChange();
}
public void work()
{
method(o1, o2);
}
public static void main(String[] args)
{
Functional f = new Functional(new Object(), new Object());
f.work();
}
}
I find the static method easier to maintain, also for people who did not write the code, since they just have to look at the method parameters - which can be an advantage in big classes. Another minor advantage is performance, because after compilation static methods get called with invokestatic which is slightly faster.
The public methods are still kept non static, since I don't want to discard OOP/encapsulation. I'm only talking about private static methods.
QUESTION
So what do you think of this apprach? Esp. what are the negativ sides my new habit of making all private methods static - within reason, as long as I don't need more than 3, 4 parameters?
IMHO You should use static methods when
there is no arguments (rare)
there is no way to extend the class of interest e.g. you want to add a method for a String.
you want to add a method to an interface (pre Java 8)
Otherwise a static method is much the same as an instance method where you are taking the first argument implicitly. i.e. you can simply transform one into the other.
Consider these recursive method calls.
class Type {
static ReturnType staticMethod(Type type, Object arg) {
return type.method(arg);
}
ReturnType method(Object arg) {
return staticMethod(this, arg);
}
}
IMHO you should use instance methods for clarity as much as possible, and leave static methods to the rare cases you have no alternative.
Note: you can use functional programming whether you use static method or not. The main principle to remember is a) always return what you create/change as a return value b) don't change any of the arguments, including this for instance methods.
This gives you the flexibility to break this a little to; only change this rather than one of the arguments (and only if you have to)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
my question is more a personnal mind challenge than a production purpose... which means that despite there are obviously better ways to achieve my goal* , I am curious about how - AND IF - I could do it this way.
*I am thus not interested in other ways atm.
I would like to "register" within a list several classes objects (Foo.class, Bar.class, etc.) sharing a common static method inherited from a common parent class.
Then I want to iterate over this list, and invoke that static method.
The following code is wrong indeed, but it may at least show what I am trying to achieve:
======== Classes definition
public class SomeGenericClass {
public abstract static String getType();
}
public class SomeSpecializedClassA extends SomeGenericClass{
public static String getType(){
return "I am of type A";
}
}
public class SomeSpecializedClassB extends SomeGenericClass{
public static String getType(){
return "I am of type B";
}
}
======== Main
class Main{
void main(){
List<Class<SomeGenericClass>> classes = new ArrayList<Class<SomeGenericClass>> ();
classes.add(SomeSpecializedClassA.class);
classes.add(SomeSpecializedClassB.class);
for((SomeGenericClass.class)Class c : classes){
System.out.println(c.getMethod("getType", null).invoke(null, null));
}
}
}
========
Any idea?
sharing a common static method inherited from a common parent class.
This is impossible; static methods do not 'do' inheritance, hence why they are called static methods. There is NO way to specify that a given class adheres to a spec, where 'the spec' involves 'has static method XYZ'.
Why do you think java has the cliché of having 'factories'? A factory is just a container concept where a single instance of a class is the place you ask questions about the concept of another class: A "PersonFactory" is a class for which usually only a single instance exists and it answers questions about persons in general. Most usually the constructor (which doesn't 'do' specs/interfaces either), but anything else goes too.
Then I want to iterate over this list, and invoke that static method.
Reflection can do this. It'd be horrible code style, hard to maintain, and all around entirely the wrong way to go about it. You're asking me: "May I have a gun because there is an annoying mosquito balanced on my left toe", and that's the bazooka. If you want to take it and let er rip, okay. Your funeral.
So what's the better way?
Why is 'static' important here? It's not. Register 'TypeOracle' objects:
public interface CommandHandlerFactory {
String getCommand();
CommandHandler makeHandler();
}
public interface CommandHandler {
void handleCommand(UserInfo sendingUser, String cmdData);
}
public class WelcomeHandler {
#Override
public void handleCommand(UserInfo sendingUser, String cmdData) {
sendMsg("Well hello there, " + sendingUser.getUserName() + "!");
}
}
channelBot.registerHandler(new CommandHandlerFactory() {
#Override
public String getCommand() {
return "/hello";
}
#Override
public CommandHandler makeHandler() {
return new WelcomeHandler();
}
}
That's how you do it in a non-blow-your-feet-right-off fashion.
NB: A comment on your question suggest using asm. This is an utterly nonsensical comment; ASM has nothing to do with this and can't help you. Ignore this comment.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I've got the following class:
class A
{
private String state;
A() { state = staticGetterCall(); } // staticGetterCall is fast
bool shouldUseState() { return state != null; }
bool getState() { return state; }
}
And then I use that class A in the following way in some other constructor:
B(...) {
...
A a = new A();
if (a.shouldUseState())
{
staticFunction2Call(a.getState());
}
}
That's the only place I use A, so I think it's a good idea to refactor this and make these 2 method static (and inline that String state):
class A
{
bool shouldUseState() { return staticGetterCall != null; }
bool getState() { return staticGetterCall; }
}
So its usage transforms to:
B(...) {
...
if (A.shouldUseState())
{
staticFunction2Call(A.getState());
}
}
Does it make sense?
Should I make a class static?
To answer your question, you need to know the good and bad points of this usage.
According to Joshua Bloch, Effective Java 2Edition, Item 1, let me list his point of view of advantages and disadvantages of static usage over constructors. So you can decide for your program effectively.
Advantages:
1. One advantage of static factory methods is that, unlike constructors, they have names.
2. A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.
3. A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.
4. A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances.
Disadvantages
1. The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.
2. A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.
In short, static factory methods and public constructors both have their uses, and it pays to understand their relative merits.
Often static factories are preferable, so avoid the reflex to provide public constructors without first considering static factories.
That's the only place I use A, so I think it's a good idea to refactor
this and make these 2 method static (and inline that String state):
It is not a reason to make an instance method static.
static members (methods or fields) are not specific to an instance of the class but are associated to the class itself.
If you define these methods as static, you will have to do some other changes : the state field should also be static and the constructor would also have no sense any longer as static method doesn't access to instance members.
So is it make really sense to make the whole class state and behavior as static ?
If the state depends on the A instance created, keep them as instance members.
And besides in a general way as you have a state in a class, make all static seems to be counter intuitive.
At last, static modifiers don't ease the switches to other implementations (and consequently also mocking in unit test). So, you should also consider this point before to make them static.
Following code makes sense to me
class A {
private static Boolean state;
A() {
state = staticGetterCall();
} // staticGetterCall is fast
private boolean staticGetterCall() {
return true;
}
static boolean shouldUseState() {
return state != null;
}
static boolean getState() {
return state;
}
}
class B {
B() {
A a = new A();
if (A.shouldUseState()) {
staticFunction2Call(a.getState());
}
}
private void staticFunction2Call(boolean state) {
}
}
There were few changes required in your code. These are trivial and I think you are aware of these.
1. Declare state field as static
2. Change datatype of state to Boolean. Right now it is declared as String.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
When it comes to Java programming you'll stumble upon this along your way. Here is an elementary answer to help new programmer learn how to use a getter method without the terminology or complexity of people is this field.
By creating an accessor method (and not creating a mutator method).
public class MyClass {
public MyClass(int v) {
this.myField = v;
}
private int myField;
public int getMyField() {
return myField;
}
}
Then you can call that "getter" in some other class with an instance of MyClass.
public class SomeOtherClass {
public static void doSomething(MyClass my) {
System.out.println(my.getMyField());
}
public static void main(String[] args) {
doSomething(new MyClass(42)); // <-- for example.
}
}
When working with Java projects you'll stubble upon "getter" methods or "get" methods. This is how I solved my problems, by following these instructions.
If you're confused on why you should use "getter" methods follow this link.
Note that this is for beginners and the language/format I use
may (and in some cases is) not be proper.
Note that you will also need to have a general concept of Java.
This is for people who don't understand some of the Java terminology
Take a look at my (example) project set up.
Package Explorer/Setup
Project Name
src
(default package/package name)
Class1.java
Class2.java
Class 1
public class Class1 {
// creates an object
static Class2 class2 = new Class2();
public static void main(String[] args) {
// this will print our method (method1) in our class (Class2)
System.out.println(class2.method1());
}
}
Class 2
public class Class2 {
// this is the method we are accessing
public double method1(){
// this is what we are returning (sending back)
return 2.5;
}
}
Output (console)
2.5
So how do we access a "getter" method?
If you haven't noticed already, we printed it in our class "Class1" using...
System.out.println(class2.method1());
we used class2. because we created an object that allows us to access our Class2. Notice that class2 is lowercase and Class2 is uppercase, this is because class2 (lowercase) is the object we've created. Thus we are using the object to use our "getter" method not our class. We create our object using...
static Class2 class2 = new Class2();
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Is it good practice in Java for a class's method to redundantly return a modified global field of that class?
Note: I edited the examples below to correct my code.
For example:
public class MyClass {
private String veryImportantString;
public static void main(String [] args) {
MyClass myObject = new MyClass();
myObject.fieldQuestion();
}
public void fieldQuestion() {
veryImportantString = "Hello, StackOverflow";
String newString = addStringToVeryImportantString(" World!");
System.out.println(newString);
}
public String addStringToVeryImportantString(String inputStr) {
this.veryImportantString = veryImportantString + inputStr;
return veryImportantString;
}
}
In the above example, addStringToVeryImportantString is returning veryImportantString, even though as a class field it has been modified and is globally available to the calling method.
In the below example, I do the same thing without returning the field:
public class MyClass {
private String veryImportantString;
public static void main(String [] args) {
MyClass myObject = new MyClass();
myObject.fieldQuestion();
}
public void fieldQuestion() {
veryImportantString = "Hello, StackOverflow";
addStringToVeryImportantString(" World!");
String newString = veryImportantString;
System.out.println(newString);
}
public void addStringToVeryImportantString(String inputStr) {
this.veryImportantString = veryImportantString + inputStr;
}
}
My question is: does it matter? Is there any difference in terms of coding standards, readability, efficiency, etc.? In a way, it makes sense to never return a global class field that a function has modified, because what is the point? The field is available anyway. On the other hand, maybe it makes sense to return the field in order to indicate that the primary purpose of the function is to modify that field and return the value.
Thanks for your input.
It is a usual coding standard for a method to either mutate an object (or variable) or get information about it but never both. Therefore a method that has a return will be assumed at first glance not to have any secondary effects (like changing veryImportantString). This is not a hard and fast rule and there are many reasons to break it but it should never be broken lightly.
Secondly the method signature in the second snippet (with a void return) could only reasonably do one thing; change veryImportantString. But with a return it could do two things; change veryImportantString and return it or return a seperate string based upon veryImportantString. As the void signature is less ambiguous it is preferable (unless theres a specific reason to do otherwise)
For your example, its not particularly important.
In general when you have a private piece of data and a public method. Your only way to get information out to the user of an instance of your class related to the private data is via returning something from a public method. Remember that most Java programs are much more complex and the need to return data related to a private field (java beans for instance) are much more common.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Right now I'm trying to figure out what exactly is a Enum in java. I know how they work and how/when to use them however I'm a little unclear on what exactly they are. Based on their behavior it seems to me they are nothing more than just a class with a private constructor. However it seems to me that the compiler is doing something special with them as Enums have a special method called values() which doesn't show up in the Enum class on the Oracle doc site.
My question is, what exactly are Enums and how does the compiler interpret them?
An enum is a class that inherits from the Enum class with (a) a private constructor, as you mentioned; and (b) a fixed, ordered list of named, final instances.
Under the covers, when you declare an enum:
public enum Foo {
A(1) {
public void bar() {
System.out.println("A#bar");
}
},
B(2) {
public void bar() {
System.out.println("B#bar");
}
},
C(3) {
public void bar() {
System.out.println("C#bar");
}
};
private Foo(int x) {
// Code goes here...
}
public abstract void bar();
}
...you can imagine the compiler generates something like this:
public class Foo extends Enum<Foo> {
public static final Foo A=new Foo(1) {
public void bar() {
System.out.println("A#bar");
}
};
public static final Foo B=new Foo(2) {
public void bar() {
System.out.println("B#bar");
}
};
public static final Foo C=new Foo(3) {
public void bar() {
System.out.println("C#bar");
}
};
private Foo(int x) {
// Code goes here...
}
}
There are a couple other things that make enums special:
The compiler knows that enums have a fixed list of instances. This allows it to do things like emit warnings if a switch doesn't have a case statement to handle each value.
Each constant has a special, compiler-generated, 0-based, monotonically increasing, dense ordinal() value assigned to it. (In other words, the first has ordinal 0, then second has ordinal 1, and so on.) This allows for extremely efficient array-based data structures like EnumMap to be created.
I'm sure I'm missing a few things, but this is a good place to start.