为什么在java中使方法变为volatile?

时间:2011-07-11 14:42:05

标签: java android

为什么方法会变得易变?如何使方法volatile改变方法的行为?

编辑:我在类对象(Java Reflection)返回的Method对象上执行了toString()。返回字符串具有针对方法名称的volatile修饰符以及公共可见性和void返回类型。研究仅得出有关物业挥发性的信息。这就是我问这个问题的原因。

方法声明是:

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

反射方法的代码:

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

方法调用:

Test.showMethods(mapView);

7 个答案:

答案 0 :(得分:38)

我强烈怀疑你所看到的是JLS为字段定义以下位的事实的副作用:

public static final int VOLATILE = 0x00000040;

以及方法的以下位:

static final int BRIDGE = 0x00000040;

请注意,它们具有相同的值(相同的位对于方法和字段具有不同的含义)。

如果你打电话,例如Modifier.toString(int)没有,正如文档所示:

  

请注意,要对已知类型的实体(例如构造函数或方法)执行此类检查,请首先使用toString或{{1}等方法中的适当掩码与constructorModifiers的参数进行AND运算}}

然后你会得到不合适的输出(包括桥接方法,例如协变返回类型自动生成,显示为'volatile')。

至少当前的OpenJDK methodModifiers过滤了这个;如果你的不是,也许你正在使用JDK的不同版本或旧版本,而这种版本没有正确执行此操作。

答案 1 :(得分:16)

你做不到。 volatile只是字段的有效修饰符。

答案 2 :(得分:9)

你读过吗

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


只是为了完成答案:

正如其他人所指出的那样:你不能让方法变得不稳定。

答案 3 :(得分:4)

你不能使方法易变。它不会编译。

答案 4 :(得分:4)

首先,Java中没有volatile方法。完全停止。

Java允许将字段声明为volatile。 Java语言规范解释了目的:

  

字段可以声明为volatile,在这种情况下,Java内存模型可确保所有线程都看到变量的一致值。

现在,如果我们尝试将其转换为方法:在 volatile方法的情况下,某些东西会确保所有线程都看到一致的字节代码< / em>用于该方法。但无论如何这都是有保证的。线程看不到类的不同版本,它们都相同(已编译)的字节码(只要它们不与类加载器一起玩耍......)。

因此Java中不需要volatile方法。

答案 5 :(得分:2)

我做了一些研究,我的结论与考恩的观点非常吻合。以下代码在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();
    }
}

输出

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

您使用的JDK是什么版本以及它是什么版本的?用于构造Method的toString()的逻辑对于细读是很有趣的。

那些对android jar感兴趣的人可以从这里下载

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

答案 6 :(得分:0)

似乎&#34;不稳定&#34;方法由Java编译器在引擎盖下生成,作为&#34;粘合方法&#34;对于通用方法。泛型将生成底层方法,这些方法只接受Object作为参数,并将它们转换为特定的泛型类型,而这些方法对于开发人员是不可见的。但是,使用method.isBridge()

可以更安全地确定这些方法