0

I was wondering how to achieve the local static variable in java. I know Java wount support it. But what is the better way to achieve the same? I donot want the other methods in my class to access the variable, but it should retain the value across the invocations of the method.

Can somebody please let me know.

Neenu
  • 6,848
  • 2
  • 28
  • 54
Lakshmikantha
  • 135
  • 1
  • 9
  • 1
    "local" and "static" are somewhat contradictory... But in any case, what's wrong with just having a regular instance variable or something and just not accessing it from other methods? – awksp Jun 13 '14 at 03:06
  • "I donot want the other methods in my class to access the variable" - then don't have them access the variable. Problem solved. Access modifiers within a class would be overkill. – user2357112 Jun 13 '14 at 03:07
  • yes, the answer http://stackoverflow.com/a/12274406/217324 to that question has the right answer: use object instances to maintain state. – Nathan Hughes Jun 13 '14 at 03:23

5 Answers5

5

I don't think there is any way to achieve this. Java does not support 'local static' a la C, and there is no way to retrofit this while still keeping your sourcecode "real Java"1.

I donot want the other methods in my class to access the variable, but it should retain the value across the invocations of the method.

The best thing would be to make it an ordinary (private) static, and then just don't access it from other methods. The last bit should be easy ... 'cos you are writing the class.


1 - I suppose you could hack something together that involves preprocessing your code, but that will make all sorts of other things unpleasant. My advice is don't go there: it is not worth the pain.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
4

Rather than trying to actually protect the variable, making the code more obscure and complicated, consider logical protection by comment and placement. I declare normal fields at the start of the class, but a field that should only be accessed from one method just before that method. Include a comment saying it should only be used in the one method:

// i should be used only in f
private int i;
/**
* Documentation for f().
*/
public void f(){
    System.out.println(i++);
}
Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
1

What you want is the ability to constraint intermediate computation results within the relevant method itself. To achieve this, you can refer to the following code example. Suppose you want to maintain a static variable i across multiple calls of m(). Instead of having such a static variable, which is not feasible for Java, you can encapsulate variable i into a field of a class A visible only to m(), create a method f(), and move all your code for m() into f(). You can copy, compile, and run the following code, and see how it works.

public class S {
  public void m() {
    class A {
      int i;

      void f() {
        System.out.println(i++);
      }
    }
    A a = new A();
    a.f();
    a.f();
    a.f();
  }
  public static void main(String[] args) {
    S s = new S();
    s.m();
  }
}
dacongy
  • 2,504
  • 3
  • 30
  • 48
  • Quite interesting... Wouldn't calling `m()` a second time result in `i` being reset though, as you create a `new A()`? Edit: I think I see what you mean, but not 100% convinced... – awksp Jun 13 '14 at 03:37
  • Yes, but you don't have to call `m()` multiple times anymore. All the work has been moved into `f()`, and you can call `f()` multiple times to do whatever you need to do. – dacongy Jun 13 '14 at 03:38
  • So if you have any work to do in between calls to `f()` you'd have to put that work into `m()` to make sure `i` doesn't get reset? – awksp Jun 13 '14 at 03:39
  • Yes, that's true. But if no other method touches the data private to `m()` (and manipulated by `f()`), why would you call it in between `f()`? I guess what's more important is to think about the use cases, which are not clear from the OP. – dacongy Jun 13 '14 at 03:45
  • This does not really protect `i` at all. Try putting `a.i = 42;` between any two calls to `a.f()`. – Patricia Shanahan Jun 13 '14 at 03:46
  • @Patricia Shanahan No, it does not protect `i`. But you, as the developer of `m()`, have the control, and you don't have to pollute class `S`. Again, depends on use case... – dacongy Jun 13 '14 at 03:49
  • I'm not sure; it's just that in my head, it makes a lot more sense that if a method were to be called consecutively that there would be *some* stuff in the middle, because otherwise it'd make more sense to bundle the repeated work into `f()` directly. This would work in that there's no way for other methods outside `m()` to see `i`, though, so I can't really complain about that. I'm just not so keen on needing to have everything be in `m()`... +1 for an intriguing (and hopefully correct) answer. – awksp Jun 13 '14 at 03:53
  • @user3580294 A more real application of this "weird" code structure is to protect methods, rather than data. Say you have non-trivial method `m` to implement, and it needs several helper methods that are only useful for `m`. Then, you can put these methods in one such `A` class, and hide them from the rest of world. You can see a lot of these in Python. But I will agree with @Patricia Shanahan that clean code and good documentation are probably more favorable. – dacongy Jun 13 '14 at 04:02
  • Hmmm... Whenever I've come across those situations I just stuck those helper methods below the "main" one, but I hadn't thought of doing something like what you did before. Can't say I've seen that too frequently in the Java classes I've seen, but maybe it just has yet to catch on or something. Do you know if the more real application would still be considered "clean"? I might just start using that now... Can't think of major disadvantages at least, beyond possibly being unconventional – awksp Jun 13 '14 at 04:10
  • @user3580294 It is probably not a good practice because it defines additional inner classes, and it makes testing difficult. Besides, you have lambda expressions for that in Java 8 :) EDIT: but complicated lambdas are usually discouraged too – dacongy Jun 13 '14 at 04:14
  • Suppose I'm staying with "regular" helper methods then... What about Python makes this kind of thing a better idea than in Java? And that's true about lambdas; unfortunately, I still have yet to get to use them in something substantial, but one day... – awksp Jun 13 '14 at 04:38
0

In theory, yes - but not in conventional manners.

What I would do to create this:

  1. Create that Object in a totally different class, under the private modifier, with no ability to be accessed directly.

  2. Use a debugging tool, such as the JDI to find that variable in the other class, get it's ObjectReference and manipulate directly or create a new variable which references to that object, and use that variable, which references to the object, in your method.

This is quite complicated, as using the JDI is tough, and you would need to run your program on 2 processes. If you want to do this, I suggest looking into the JDI, but my honest answer would be to look for another solution.

Dean Leitersdorf
  • 1,303
  • 1
  • 11
  • 22
0

Based on dacongy's idea of using a method local class I created a simple solution:

public class Main {
   public static String m() {
      class Statics {
         static String staticString;
      }
      if (Statics.staticString == null)
         Statics.staticString = "My lazy static method local variable";
      return Statics.staticString;
   }

}
RedCrafter LP
  • 174
  • 1
  • 8