Подтвердить что ты не робот

Зачем использовать метод volatile в java?

Почему метод должен быть изменен? Как изменение метода изменяет метод?

Изменить: Я сделал toString() для объекта Method, возвращаемого объектом класса (Java Reflection). В возвращаемой строке был измененный модификатор имени метода вместе с общедоступной видимостью и типом возвращаемого значения. Исследования дали только информацию об изменчивости свойств. Вот почему я задал этот вопрос.

Объявление метода:

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

Ответ 1

Я сильно подозреваю, что то, что вы видите, является побочным эффектом того факта, что JLS определяет следующий бит для полей:

public static final int VOLATILE = 0x00000040;

и следующий бит для методов:

static final int BRIDGE = 0x00000040;

Обратите внимание, что они имеют одинаковое значение (один и тот же бит имеет различное значение для методов и полей).

Если вы звоните, например. Modifier.toString(int) без, как предполагает документация:

Обратите внимание, что для выполнения такой проверки для известного типа объекта, такого как конструктор или метод, сначала И аргумент toString с соответствующей маской от метода, такого как constructorModifiers или methodModifiers.

то вы получите неадекватный вывод (в том числе мостовые методы, автогенерируемые, например, для ковариантного типа возврата, отображаемые как "изменчивые" ).

По крайней мере, текущий OpenJDK Method.toString() фильтрует это; если у вас нет, возможно, вы используете другую или более старую версию JDK, которая не делает это правильно.

Ответ 2

Вы не можете. volatile является только допустимым модификатором для поля.

Ответ 4

Вы не можете сделать метод изменчивым. Он не будет компилироваться.

Ответ 5

Прежде всего, нет методов volatile в Java. Полная остановка.

Java позволяет объявлять поля как volatile. Спецификация языка Java объясняет цель:

Поле может быть объявлено изменчивым, и в этом случае модель памяти Java гарантирует, что все потоки будут видеть согласованное значение для переменной.

Теперь, если мы попытаемся перевести его на методы: в случае летучего метода что-то будет гарантировать, что все потоки будут видеть согласованный байтовый код для метода. Но это все равно гарантировано. Темы не видят разные версии класса, все они видят один и тот же (скомпилированный) байт-код (если они не играют трюки с загрузчиками классов...).

Поэтому в Java нет необходимости в методах volatile.

Ответ 6

Я сделал некоторые исследования, и мои выводы близко отражают Коуэна. Следующий код создает правильный вывод на 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 вы используете и какая версия? Логику, используемую для построения метода toString(), было бы интересно изучить.

Те, кто интересуется андроидным банком, могут скачать его здесь

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

Ответ 7

Кажется, что "неустойчивые" методы создаются под капотом компилятором Java, как "методы клея" для общих методов. Generics будет производить под капотом методы, которые будут принимать только объект как параметры и отнести их к конкретному родовому типу, в то время как эти методы невидимы для разработчика. Существует более безопасный способ определения этих методов, однако, используя method.isBridge()