简体   繁体   中英

Why make a method volatile in java?

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);

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 eg 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 eg 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.

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

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.

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

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.

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

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM