Как создать синтетические поля в java?

  1. Как можно создать синтетические поля в Java?

  2. можно ли создавать синтетические поля в java только во время выполнения? Если нет: существует ли стандартный способ для этого во время компиляции (без изменения некоторых байтов в файле класса)

2 ответов


они создаются компилятором, когда "странности" языка требуют от них. Простой пример этого-использование внутреннего класса:

public class Test
{
    class Inner
    {
    }
}

на Test.Inner класс будет иметь синтетическое поле для представления соответствующего экземпляра Test класса.

мы можем немного расширить этот код, чтобы показать, что поле:

import java.lang.reflect.*;

public class Test
{
    public static void main(String[] args)
    {
        for (Field field : Inner.class.getDeclaredFields())
        {
            System.out.println(field.getName() + ": " + field.isSynthetic());
        }
    }

    class Inner
    {
    }
}

С моим компилятором, который печатает:

this: true

Да, это выполнимо, и это называется Время загрузки ткачества. По сути, вам нужно будет определить свой собственный загрузчик классов, который будет решать по классу за классом, следует ли изменять файл класса, который должен быть загружен; это означает, что вам нужно будет проверить двоичный класс, который загружается, возможно, изменить его, а затем передать его в JVM для определения/разрешения. Это немного громоздко, сложно и склонно к ClassCastExceptions (тот же класс, определенный в 2 разных загрузчиках классов, будет дайте 2 разных класса, которые не совместимы с назначением).

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

уже есть инструменты, которые могут помочь вам - см., например, AspectJ как полнофункциональную языковую модификацию или что-то вроде BCEL или javassist, что позволяет писать такие инструменты ткачества.