In Java can a method have anything close to a static variable in C?Although Java doesn't provide one
That is,it would be initialized only once and keep latest value in subsequent recursive invocations
I could pass it back to the method to have the latest value and achieve 'initalize only once' based on some condition which holds true only once
int fun(.....,Nthcall,PseudoStatic)
{if(NthCall==1)
PseudoStatic=10
//rest of code
Pseudostatic=100
fun(.....,Nthcall+1,PseudoStatic)
}
Isn't there something better?
Why not just declare a variable static to the class ? See the tutorial on instance and class variables for more info.
Note that this isn't thread-safe if multiple threads use the same class. and consequently you may be better off defining a class member variable per invocation.
We can do something like this
public void test()
{
StaticVar<Integer> s1 = new StaticVar<Integer>(){};
StaticVar<Long> s2 = new StaticVar<Long>(){};
Integer v1 = s1.get();
System.out.println(v1);
s1.set( v1==null? 1 : v1+1 );
Long v2 = s2.get();
System.out.println(v2);
s2.set( v2==null? 1 : v2*2 );
}
public abstract class StaticVar<V>
{
public V get()
{
return (V)class2value.get(this.getClass());
}
public void set(V value)
{
class2value.put(this.getClass(), value);
}
static WeakHashMap<Class,Object> class2value = new WeakHashMap<>();
}
It's not thread safe though. We can simply add synchronized(class2value). Or use a weak concurrent hash map.
Related
I would like to pass a reference to a primitive type to a method, which may change it.
Consider the following sample:
public class Main {
Integer x = new Integer(42);
Integer y = new Integer(42);
public static void main(String[] args) {
Main main = new Main();
System.out.println("x Before increment: " + main.x);
// based on some logic, call increment either on x or y
increment(main.x);
System.out.println("x after increment: " + main.x);
}
private static void increment(Integer int_ref) {
++int_ref;
}
}
The output running the sample is:
x Before increment: 42
x after increment: 42
Which means int_ref was past to the function by value, and not by reference, despite my optimistic name.
Obviously there are ways to work around this particular example, but my real application is way more complex, and in general one would imagine that a "pointer" or reference to integer would be useful in many scenarios.
I've tried to pass Object to the function (then casting to int), and various other methods, with no luck. One workaround that seems to be working would be to define my own version of Integer class:
private static class IntegerWrapper {
private int value;
IntegerWrapper(int value) { this.value = value; }
void plusplus() { ++value; }
int getValue() { return value; }
}
Doing this, and passing a reference to IntegerWrapper does work as expected, but to my taste it seems very lame. Coming from C#, where boxed variable just remain boxed, I hope I just miss something.
EDIT:
I would argue my question isn't a duplicate of Is Java "pass-by-reference" or "pass-by-value"?, as my question isn't theoretical, as I simply seek a solution. Philosophically, all method calls in all languages are pass-by-value: They either pass the actual value, or a reference to the value - by value.
So, I would rephrase my question: What is the common paradigm to workaround the issue that in java I'm unable to pass a reference to an Integer. Is the IntegerWrapper suggested above a known paradigm? Does a similar class (maybe MutableInt) already exist in the library? Maybe an array of length 1 a common practice and has some performance advantage? Am I the only person annoyed by the fact he can store a reference to any kind of object, but the basic types?
Integer is immutable, as you may notice.
Your approach with private static class IntegerWrapper is correct one. Using array with size 1 is also correct, but in practice I have never seen using array for this case. So do use IntegerWrapper.
Exactly the same implementation you can find in Apache org.apache.commons.lang3.mutable.MutableInt.
In your example you also can provide Main instance to the static method:
public class Main {
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
incrementX(main);
}
private static void incrementX(Main main) {
main.x++;
}
}
And finally, from Java8 you could define an inc function and use it to increment value:
public class Main {
private static final IntFunction<Integer> INC = val -> val + 1;
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
main.x = INC.apply(main.x);
}
}
In Java 8 I want to create something that returns an argument or creates an instance if the argument is null.
I could do this by creating a static method or a UnaryOperator. Are the following approaches technically the same or are there technical differences that I should be aware of with either approach:
Static Method
static Cat initOrReturn(Cat c) {
if (c==null) {
return new Cat();
}
return c;
}
Function
UnaryOperator<Cat> initOrReturn = c -> {
if (c==null) {
return new Cat();
}
return c;
}
First your code has syntax error, in the second block first line between c and { there should be a ->.
The second one creates an anonynous object, the first one only creates a static method.
So they're not the same.
Also, static methods can be used in stream API.
If you have:
class A {
static Object a(Object x) { return x; /* replace with your code */ }
}
You can:
xxxList().stream().map(A::a)
Creating a method is often considered dirty, because it's globally visible.
It's recommended to use lambda expressions without declaring a variable.
You can think about function as a "value" - something that can be stored to variable, and passed around.
This "value" can be used as e.g. method parameter to (during runtime) dynamically change part of method implementation.
Take a look at this basic example. Hope that can illustrate idea:
static Number functionsUsageExample(Integer someValue, UnaryOperator<Number> unaryOperator) {
if (someValue == 1) {
//do something
}
Number result = unaryOperator.apply(someValue); // dynamically apply supplied implementation
// do something else
return result;
}
public static void main(String[] args) {
UnaryOperator<Number> add = i -> i.doubleValue() + 20;
UnaryOperator<Number> multiply = i -> i.intValue() * 3;
var additionResult = functionsUsageExample(1, add);
var multiplicationResult = functionsUsageExample(1, multiply);
//additionResult value is: 21.0
//multiplicationResult value is: 3
}
Function can be also used as a 'helper methods' stored inside method block. This way you will not corrupt class scope with method that is used only in one place.
I haven't been coding anything for a while now and I decided to practice a bit. I came up with this issue at the very beginning of my program and I spent last night trying to figure out or find a way around this problem but I didn't get any expected results.
First, let's see the class:
public class Task {
private static int priority;
private static int taskTime;
private static boolean solved;
public void setPriority(int p){this.priority = p;}
public void setTasktime(int t){this.taskTime = t;}
public void setSolved(boolean s){solved = s;}
public int getPriority(){return this.priority;}
public int getTaskTime(){return this.taskTime;}
public boolean getSolved(){return this.solved;}
public Task(int p, int t){
this.priority = p;
this.taskTime = t;
this.solved = false;
}
public static class ComparePriority implements Comparator<Task>{
#Override
public int compare(Task t1, Task t2){
return Integer.compare(t1.getPriority(), t2.getPriority());
}
}
}
Now, this is the piece of code I am trying to run:
public class main {
public static void main(String[] args) {
Task t1 = new Task(20,1);
Task t2 = new Task(13,2);
Task t3 = new Task(10,5);
ArrayList<Task> t = new ArrayList<Task>();
t.add(t2);
t.add(t3);
t.add(t1);
System.out.println("List size: " + t.size());
System.out.println("T1 object's priority: " + t1.getPriority());
System.out.println("T2 object's priority: " + t2.getPriority());
System.out.println("T3 object's priority: " + t3.getPriority());
for(int i=0;i<t.size();i++){
System.out.println("Current object task time: "+ t.get(i).getTaskTime());
System.out.println("Current index:" + i);
}
Collections.sort(t, new Task.ComparePriority());
for(int i=0;i<t.size();i++){
System.out.println("Current object task time (post sort): " + t.get(i).getTaskTime());
System.out.println("Current index: " + i);
}
}
I understand that these attributes were defined in a static way and I should be accessing them as Class.method();
If I were to instantiate 3 objects (as used as example up above), is there any way to access them statically but still get every piece of information read from the object to be unique instead of "the same"?
Also why is accessing them non-statically discouraged?
You are asking for contradicting things.
access them statically
contradicts
still get every piece of information read from the object to be unique instead of "the same"
If you wish the former, you should expect the same value to be seen by all instances.
If you wish the latter, don't define them as static.
As for accessing them non-statically, as far as I know it makes no difference. They only reason I'd avoid accessing static members non-statically (i.e. by dereferencing an object of that class) is readability. When you read object.member, you expect member to be a non-static member. When you read ClassName.member you know it's a static member.
When a static method is called, it deals with everything on the class-level, rather than the object-level. This means that the method has no notion of the state of the object that called it - it will be treated the same as for every object that calls it. This is why the compiler gives a warning. It is misleading to use a static method with the form a.Method() because it implies that the method is invoked on the object, when in the case of static methods, it is not. That's why it's bad practice to call a static method on an instance of an object.
I think you misunderstand the difference between class variable and static variable. Program has only one value for static variable mean while every object has it own value for a class variable. It is also considered misleading to use this with static members.
Accessing them non-statically is not discouraged at all in programming, but actually encouraged. If you want to access things non-statically, try putting that code in another class in a method. Then in this class put
public static void main(String[] args) {
AnotherClass ac = new AnotherClass();
ac.initializeProcess()
}
I don't know why people like downgrading questions, I guess they think they were never new at all.
Update:
Static objects don't get thrown in the garbage-collector too quickly but it is saved as long there are references to it; static objects can cause memory issues
https://stackoverflow.com/a/572550/1165790
I want to use this feature in Java because the function that I'm designing is called rarely (but when it is called, it starts a recursive chain) and, therefore, I do not want to make the variable an instance field to waste memory each time the class is instantiated.
I also do not want to create an additional parameter, as I do not want to burden external calls to the function with implementation details.
I tried the static keyword, but Java says it's an illegal modifier. Is there a direct alternative? If not, what workaround is recommended?
I want it to have function scope, not class scope.
I want it to have function scope, not class scope.
Then you are out of luck. Java provides static (class scoped), instance and local variables. There is no Java equivalent to C's function-scoped static variables.
If the variable really needs to be static, then your only choice is to make it class scoped. That's all you've got.
On the other hand, if this is a working variable used in some recursive method call, then making it static is going to mean that your algorithm is not reentrant. For instance, if you try to run it on multiple threads it will fall apart because the threads will all try to use the same static ... and interfere with each other. In my opinion, the correct solution would be either to pass this state using a method parameter. (You could also use a so-called "thread local" variable, but they have some significant down-sides ... if you are worrying about overheads that are of the order of 200 bytes of storage!)
How are you going to keep a value between calls without "wasting memory"? And the memory consumed would be negligible.
If you need to store state, store state: Just use a static field.
Caution is advised when using static variables in multi-threaded applications: Make sure that you synchronise access to the static field, to cater for the method being called simultaneously from different threads. The simplest way is to add the synchronized keyword to a static method and have that method as the only code that uses the field. Given the method would be called infrequently, this approach would be perfectly acceptable.
Static variables are class level variables. If you define it outside of the method, it will behave exactly as you want it to.
See the documentation:
Understanding instance and Class Members
The code from that answer in Java...
public class MyClass {
static int sa = 10;
public static void foo() {
int a = 10;
a += 5;
sa += 5;
System.out.println("a = " + a + " sa = " + sa);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
foo();
}
}
}
Output:
$ java MyClass
a = 15 sa = 15
a = 15 sa = 20
a = 15 sa = 25
a = 15 sa = 30
a = 15 sa = 35
a = 15 sa = 40
a = 15 sa = 45
a = 15 sa = 50
a = 15 sa = 55
a = 15 sa = 60
sa Only exists once in memory, all the instances of the class have access to it.
Probably you got your problem solved, but here is a little more details on static in Java. There can be static class, function or variable.
class myLoader{
static int x;
void foo(){
// do stuff
}
}
versus
class myLoader{
static void foo(){
int x;
// do stuff
}
}
In the first case, it is acting as a class variable. You do not have to "waste memory" this way. You can access it through myLoader.x
However, in the second case, the method itself is static and hence this itself belongs to the class. One cannot use any non-static members within this method.
Singleton design pattern would use a static keyword for instantiating the class only once.
In case you are using multi-threaded programming, be sure to not generate a race condition if your static variable is being accessed concurrently.
I agree with Bohemian it is unlikely memory will be an issue. Also, duplicate question: How do I create a static local variable in Java?
In response to your concern about adding an additional parameter to the method and exposing implementation details, would like to add that there is a way to achieve this without exposing the additional parameter. Add a separate private function, and have the public function encapsulate the recursive signature. I've seen this several times in functional languages, but it's certainly an option in Java as well.
You can do:
public int getResult(int parameter){
return recursiveImplementation(parameter, <initialState>)
}
private int recursiveImplementation(int parameter, State state){
//implement recursive logic
}
Though that probably won't deal with your concern about memory, since I don't think the java compiler considers tail-recursive optimizations.
The variables set up on the stack in the recursive call will be function (frame) local:
public class foo {
public void visiblefunc(int a, String b) {
set up other things;
return internalFunc(a, b, other things you don't want to expose);
}
private void internalFunc(int a, String b, other things you don't want to expose) {
int x; // a different instance in each call to internalFunc()
String bar; // a different instance in each call to internalFunc()
if(condition) {
internalFunc(a, b, other things);
}
}
}
Sometimes state can be preserved by simply passing it around. If required only internally for recursions, delegate to a private method that has the additional state parameter:
public void f() { // public API is clean
fIntern(0); // delegate to private method
}
private void fIntern(int state) {
...
// here, you can preserve state between
// recursive calls by passing it as argument
fIntern(state);
...
}
How about a small function-like class?
static final class FunctionClass {
private int state1; // whichever state(s) you want.
public void call() {
// do_works...
// modify state
}
public int getState1() {
return state1;
}
}
// usage:
FunctionClass functionObject = new FunctionClass();
functionObject.call(); // call1
int state1AfterCall1 = functionObject.getState1();
functionObject.call(); // call2
int state1AfterCall2 = functionObject.getState1();
I have a class with several methods. Now I would like to define a helper method that should be only visible to method A, like good old "sub-functions" .
public class MyClass {
public methodA() {
int visibleVariable=10;
int result;
//here somehow declare the helperMethod which can access the visibleVariable and just
//adds the passed in parameter
result = helperMethod(1);
result = helperMethod(2);
}
}
The helperMethod is only used by MethodA and should access MethodA's declared variables - avoiding passing in explicitly many parameters which are already declared within methodA.
Is that possible?
EDIT:
The helper mehod is just used to avoid repeating some 20 lines of code which differ in only 1 place. And this 1 place could easily be parameterized while all the other variables in methodA remain unchanged in these 2 cases
Well you could declare a local class and put the method in there:
public class Test {
public static void main(String[] args) {
final int x = 10;
class Local {
int addToX(int value) {
return x + value;
}
}
Local local = new Local();
int result1 = local.addToX(1);
int result2 = local.addToX(2);
System.out.println(result1);
System.out.println(result2);
}
}
But that would be a very unusual code. Usually this suggests that you need to take a step back and look at your design again. Do you actually have a different type that you should be creating?
(If another type (or interface) already provided the right signature, you could use an anonymous inner class instead. That wouldn't be much better...)
Given the variables you declare at the top of your method can be marked as final (meaning they don't change after being initialized) You can define your helper method inside a helper class like below. All the variables at the top could be passed via the constructor.
public class HelperClass() {
private final int value1;
private final int value2;
public HelperClass(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
public int helperMethod(int valuex) {
int result = -1;
// do calculation
return result;
}
}
you can create an instance of HelperClass and use it inside the method
It is not possible. It is also not good design. Violating the rules of variable scope is a sure-fire way to make your code buggy, unreadable and unreliable. If you really have so many related variables, consider putting them into their own class and giving a method to that class.
If what you mean is more akin to a lambda expression, then no, this is not possible in Java at this time (but hopefully in Java 8).
No, it is not possible.
I would advise you create a private method in your class that does the work. As you are author of the code, you are in control of which other methods access the private method. Moreover, private methods will not be accessible from the outside.
In my experience, methods should not declare a load of variables. If they do, there is a good chance that your design is flawed. Think about constants and if you couldn't declare some of those as private final variables in your class. Alternatively, thinking OO, you could be missing an object to carry those variables and offer you some functionality related to the processing of those variables.
methodA() is not a method, it's missing a return type.
You can't access variables declared in a method from another method directly.
You either has to pass them as arguments or declare methodA in its own class together with the helpermethods.
This is probably the best way to do it:
public class MyClass {
public void methodA() {
int visibleVariable=10;
int result;
result = helperMethod(1, visibleVariable);
result = helperMethod(2, visibleVariable);
}
public int helperMethod(int index, int visibleVariable) {
// do something with visibleVariable
return 0;
}
}