18

Why would a method be made volatile? How does making a method volatile change the method's behavior?

Edit: I did a toString() on a Method object returned by a class object (Java Reflection). The return string had a volatile modifier against the method name along with public visibility and void return type. Research yielded only information on volatile for properties. This is why I asked this question.

The method declaration was:

public volatile org.osmdroid.api.IGeoPoint org.osmdroid.views.MapView.getMapCenter()

Code for the Reflection Method:

public static class Test {
    public static void showMethods(Object target) {
        Class<?> clazz = target.getClass();
        for (Method method : clazz.getMethods()) {
            if (method!=null) {
                System.out.println(method.toString());
            }
        }
    }
}

Method invocation:

Test.showMethods(mapView);
Gray
  • 115,027
  • 24
  • 293
  • 354
Raj
  • 3,051
  • 6
  • 39
  • 57

7 Answers7

40

I strongly suspect that what you're seeing is a side-effect of the fact that the JLS defines the following bit for fields:

public static final int VOLATILE = 0x00000040;

and the following bit for methods:

static final int BRIDGE = 0x00000040;

Note that they have the same value (the same bit has a different meaning for methods and fields).

If you call e.g. Modifier.toString(int) without, as the documentation suggests:

Note that to perform such checking for a known kind of entity, such as a constructor or method, first AND the argument of toString with the appropriate mask from a method like constructorModifiers or methodModifiers.

then you'll get inappropriate output (including bridge methods, autogenerated for e.g. covariant return type, showing up as 'volatile').

At least the current OpenJDK Method.toString() filters this out; if yours isn't, perhaps you're using a different or older version of the JDK which doesn't do this correctly.

Cowan
  • 37,227
  • 11
  • 66
  • 65
  • My java -version output: java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9.7) (6b20-1.9.7-0ubuntu1) OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode) Too old? – Raj Jul 13 '11 at 05:22
  • Another hint would be that (I think) bridge methods won't show up in `getDeclaredMethods()`, just `getMethods()`. – Cowan Jul 15 '11 at 02:15
16

You can't. volatile is only a valid modifier for a field.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
9

have you read

http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html


just to make the answer complete :

as everybody else is pointing out : you can't make a method volatile.

Jason Rogers
  • 19,194
  • 27
  • 79
  • 112
  • 1
    Well, IMO, all the answers here should be comments so that would be only one – Op De Cirkel Jul 11 '11 at 14:47
  • @Op De Cirkel, I made this answer an exception because only a link was provided, which is what's typically done in comments. – mre Jul 11 '11 at 14:48
  • +1: Assuming the OP wants to know when to use volatile, this does lead to the answer. – Peter Lawrey Jul 11 '11 at 15:00
  • 1
    following your logic all the post here except for Andreas_D should be comments. as an IT I believe in not rewriting something if its already well done elsewhere, so in my opinion for a question like this where there is no precise error to answer but just a general misunderstanding can be answered with just a weblink. – Jason Rogers Jul 11 '11 at 16:09
4

You can't make a method volatile. It won't compile.

John Vint
  • 39,695
  • 7
  • 78
  • 108
4

First of all, no volatile methods in Java. Full stop.

Java allows to declare fields as volatile. The Java language spec explains the purpose:

A field may be declared volatile, in which case the Java memory model ensures that all threads see a consistent value for the variable.

Now, if we try to translate it to methods: in case of a volatile method something would ensure, that all threads see a consistent byte code for the method. But that is guaranteed anyway. Threads don't see different versions of a class, they all see the same (compiled) byte code (as long as they don't play tricks with classloaders...).

So there is no need for volatile methods in Java.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
2

I did some research and my conclusions closely mirror Cowan's. The following code produces the correct output on a Sun JDK 1.6_13

public void go()
{

    try
    {
        Class<?> forName = Class.forName("org.osmdroid.views.MapView");
        Method[] methods = forName.getMethods();
        for(Method m : methods)
        {
            String name = m.getName();
            if(name.equals("getMapCenter"))
            {
                System.out.println(m);
            }
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

Output

public org.osmdroid.api.IGeoPoint org.osmdroid.views.MapView.getMapCenter()
public org.osmdroid.util.GeoPoint org.osmdroid.views.MapView.getMapCenter()

What JDK are you using and what version is it ? The logic used to construct the Method's toString() would be interesting to peruse.

Those interested in the android jar can download it from here

http://code.google.com/p/osmdroid/downloads/list http://www.jarvana.com/jarvana/archive-details/com/google/android/android/1.5_r3/android-1.5_r3.jar

Deepak Bala
  • 11,095
  • 2
  • 38
  • 49
  • The version of Java: java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9.7) (6b20-1.9.7-0ubuntu1) OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode) – Raj Jul 13 '11 at 05:20
  • 1
    Got the same output on the Open-JDK in Ubuntu ' java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9.7) (6b20-1.9.7-0ubuntu1) OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)' – Deepak Bala Jul 13 '11 at 06:04
0

It seems that "volatile" methods are produced under the hood by the Java compiler, as "glue methods" for generic methods. Generics will produce under the hood methods which will accept only Object as parameters, and cast them to the specific generic type, while these methods are invisible to the developer. There is a safer way to determine these methods though, by using the method.isBridge()

Panayotis
  • 1,792
  • 23
  • 32