Отражение на Java, добавете променлив модификатор към частно статично поле

Възможно ли е да добавите модификатора volatile към поле, което е лично и статично?

Примерен код

// I don't know when test is initalized
public class Test {
    private static String secretString;

    public Test() {
        secretString = "random";
    }
}

public class ReflectionTest extends Thread {
    public void run() {
        Class<?> testClass = Class.forName("Test");
        Field testField = testClass.getDeclaredField("secretString");

        while (testField.get(null) == null) {
            // Sleep, i don't know when test is initalized
            // When it'is i need the String value
            // But this loop never end.
        }
    }
}

Мисля, че ако задам полето volatile, цикълът завършва без никакъв проблем


person Emax    schedule 19.12.2014    source източник
comment
добавете крайна ключова дума защо искате volatile?   -  person SMA    schedule 19.12.2014
comment
Искате да кажете да напишете private static volatile String secretString? Да, това е възможно. Ако нямате предвид това, тогава въпросът ви е подвеждащ и неточен.   -  person Marko Topolnik    schedule 19.12.2014
comment
Вместо да питате дали е възможно и дали ще помогне, защо просто не опитате да го направите и да видите какво ще се случи?   -  person Dima    schedule 19.12.2014
comment
@Dima не знам как да постъпя   -  person Emax    schedule 19.12.2014
comment
@MarkoTopolnik Да, искам това   -  person Emax    schedule 19.12.2014
comment
Така че, напишете private static volatile String secretString. Опитахте ли го вече?   -  person Marko Topolnik    schedule 19.12.2014
comment
@MarkoTopolnik Нямам достъп до тестовия клас   -  person Emax    schedule 19.12.2014
comment
Така че отново не сте изяснили какво всъщност искате. Това не е добър начин общността да ви помогне.   -  person Marko Topolnik    schedule 19.12.2014
comment
@MarkoTopolnik Искам да прочета полето secretString от друга нишка, но не мога поради синхронизация, така че трябва да добавя променлив модификатор към secretString и след това да прочета, но не знам как да направя   -  person Emax    schedule 19.12.2014
comment
Основното нещо, което попитах в началото, беше дали искате или не искате да пишете private static volatile. Вашият отговор беше да, искам това, вместо да посочвам коя от двете опции искате. Вашият коментар по-горе за пореден път не уточнява това, въпреки че вече е станало полуясно. Искате да добавите модификатора чрез отражение по време на изпълнение. Не можете, отражението не е API, който променя класовете.   -  person Marko Topolnik    schedule 19.12.2014
comment
@MarkoTopolnik Моят въпрос е: Имам клас с име Test, не знам кога и къде е инициализиран, искам да прочета поле от този клас, така че отварям друга нишка и казвам в цикъл, когато стойността на полето е t е равно на нула, тестовият клас се инициализира и след това прочитам стойността на полето, но цикълът никога не свършва, така че мисля, че това е проблем на синхронизацията поради тази причина, мисля, че ако задам полето volatile, този проблем ще реши, но аз не знам как да настроя модификатора volatile по време на изпълнение за полето   -  person Emax    schedule 19.12.2014


Отговори (1)


Ако нямате достъп до класа, не можете да го промените.

Вместо това намерете кода, който го инстанцира, и добавете синхронизиран блок около него:

synchronized(Test.class) {
   new Test();
}

Сега в кода на вашата нишка направете:

while(true) {
   synchronized(Test.class) {
       if(testField.get(null) == null) break;
   }
   // ... whatever 
}

Мога ли да попитам защо ви трябва това? Ако едно поле е направено лично, обикновено има причина за това. Вие заобикаляте намерението на създателя на класа с използването на отражение ... Освен това инициализирането на статични полета в конструктор на екземпляр изглежда ... подозрително :-/

person Dima    schedule 19.12.2014
comment
Това не решава проблема ми, полето винаги е нула - person Emax; 19.12.2014
comment
Ако полето винаги е нула, тогава вашият цикъл никога няма да излезе :) Това няма нищо общо с нишки или волатилност. Имате нужда от код, за да промените стойността на полето. - person Dima; 19.12.2014
comment
трябва да прочета стойността на полето, когато тестовият клас е инициализиран - person Emax; 19.12.2014
comment
Ако полето винаги е нула, тогава класът не се инициализира. - person Dima; 19.12.2014
comment
Сигурен съм, че класът е инициализиран - person Emax; 19.12.2014
comment
Когато класът се инициализира, полето се задава на някаква различна от нула стойност, нали? Ако е така, тогава или класът никога не се инициализира, или полето не винаги е нула. Ако сте сигурни в обратното, значи грешите очевидно. Това е проста логика, няма място за спор. - person Dima; 19.12.2014
comment
Класът, който декларира полето, е единичен клас. Опитвам се да получа екземпляра, той е деклариран като частен статичен тестов екземпляр; в конструктора има Test.instance = this; и System.out, виждам System.out, но моят код винаги чете нула - person Emax; 19.12.2014
comment
И вие създавате екземпляра в рамките на синхронизиран блок? И вашият тест се прави в рамките на синхронизиран блок? И вие синхронизирате едно и също нещо и в двата случая? Тогава трябва да има нещо нередно с вашата аура, което магически пречи на програмата ви да работи. Покажете пълния код, който демонстрира проблема. Пълен изходен код, който може да бъде компилиран и стартиран. - person Dima; 19.12.2014
comment
аз не конструирам класа, но знам, че не е синхронизиран - person Emax; 19.12.2014
comment
в такъв случай нямате късмет. Ако не е синхронизиран, няма да видите промените, направени в друга нишка, докато кеш паметта на процесора не бъде изчистена, което може никога да не се случи. Ще го кажа отново: може би е декларирано като частно с причина. Не се предполага, че имате достъп до това поле. - person Dima; 19.12.2014