Скала расширить поле черты не найдено - PullRequest
0 голосов
/ 23 февраля 2019

У меня есть черта scala с общедоступным UUID, который имеет значение по умолчанию:

trait pet {
    var uuid_ : UUID = UUID.randomUUID
}

Теперь я создаю несколько классов, также в scala:

class dog extends pet {
    var foo = 1
}
class cat extends pet {
}
class fish extends pet {
}

После этого ясоздал метод в Java (старый проект со смешанными обоими языками).
Здесь снят с моей проблемой.В переменной somePet есть экземпляр dog, cat или fish.Но не ясно, что именно из них:

// printing all variables in the console for human testing
Serializer.printAllFields(somePet);

// The somePet Variable must be a pet
if(!pet.class.isAssignableFrom(somePet.getClass()))
    throw new Exception("Not a pet.");

// get the UUID of the pet
UUID uuid_;
try {
    Field f = pet.class.getField("uuid_");
    f.setAccessible(true);
    uuid_ = (UUID) f.get(somePet);
}catch(Exception e){
    // no uuid found
    throw e;
}

Но когда я запускаю код, я получаю следующую ошибку:

Exception in thread "main" java.lang.NoSuchFieldException: uuid_

И трассировка стека указывает на строку с Field f = pet.class.getField("uuid_");.
Но что не так с кодом?
Я подумал, что альтернативой была замена этой точной строки на:

Field f = ntObj.getClass().getField("uuid_");

Но это также не помогло.
Так где же переменная uuid_?
Потому что, когда я распечатываю все переменные в консоли текущего somePet с помощью сериализатора, я получаю что-то вроде

* cat.uuid_ = 34d7a781-472d-4d98-861e-7cff08045445;

или

* dog.foo = 1
* dog.uuid_ = 34d7a781-472d-4d98-861e-7cff08045445;

вконсоль.
Так что переменная uuid_ там со значением по умолчанию.
(я использую сериализатор из этот пост )

Так как мне получитьuuid_ переменная в моем фрагменте Java?

1 Ответ

0 голосов
/ 23 февраля 2019

Прежде всего, нет такого Serializer в пакете java.util, поэтому вы используете что-то еще.

trait переводится в Java interface, который не может иметь поля как таковые.
Однако вы пытаетесь получить доступ к полю через Pet интерфейс

pet.class.getField(...)

Это не сработает.Вам нужно искать поле внутри бетона class.
Кроме того, по умолчанию это поле будет private, поскольку доступ предоставляется через getter.

getFieldМетод может извлекать каждое поле public для всей иерархии классов (что означает даже суперклассы), тогда как getDeclaredField может извлекать поля protected и private, но только в том классе, который вы вызываете.от.Вам также необходимо вызвать setAccessible(true), потому что

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

Правильный код будет (dog - конкретный экземпляр)

final Field uuid = dog.getClass().getDeclaredField("uuid_");
uuid.setAccessible(true);
final Object o = uuid.get(dog);

Или с использованиемавтоматический getter

final Method uuid = dog.getClass().getMethod("uuid_");
final Object o = uuid_.invoke(dog);
...