Как определить, был ли возвращенный объект создан во время выполнения метода - Java - PullRequest
1 голос
/ 03 июля 2010

Исходный вопрос: Учитывая метод, который я хотел бы определить, создается ли возвращенный объект в ходе выполнения этого метода.Какой вид статического анализа можно или нужно использовать?

Переработанные вопросы: учитывая метод, который я хотел бы определить, может ли объект, созданный в этом методе, быть возвращен этим методом.Итак, если я пройду и добавлю все экземпляры возвращаемого типа в этом методе в набор, будет ли анализ, который скажет мне для каждого члена набора, может ли он быть возвращен или нет.Кроме того, можно ли не ограничивать набор одним методом, но все методы, вызываемые исходным методом для учета делегирования?

Это не относится ни к какому вызову.

Этопохоже, что метод анализа побега может быть ответом.

Спасибо всем за ваши предложения.

Ответы [ 5 ]

1 голос
/ 03 июля 2010

Ваш вопрос, по-видимому, является либо простым «достигающим» анализом («достигает ли новое значение операторы возврата»), если вас интересует любой вызов, и только если локальный метод new создает значение. Если вам нужно знать, может ли какой-либо вызов вернуть новое значение из какого-либо подкомпьютера, вам нужно вычислить возможный граф вызовов и определить, может ли какая-либо вызванная функция вернуть новое значение или передать новое значение из вызываемой функции ее родителю.

Существует несколько платформ статического анализа Java.

SOOT - это структура анализа на основе байт-кода. Вы могли бы реализовать свой статический запрос, используя это.

DMS Software Reengineering Toolkit - это общий механизм для создания пользовательских анализаторов и инструментов преобразования. Он имеет полный интерфейс Java и вычисляет различные полезные базовые анализы (цепочки определения / использования, граф вызовов) для кода source . Он может обрабатывать файлы классов, но в настоящее время только для получения информации о типах.

Если вам нужен динамический анализ, либо сам по себе, либо в качестве способа ужесточения статического анализа, DMS можно использовать для произвольной обработки исходного кода, вставляя код для отслеживания распределений.

0 голосов
/ 03 июля 2010

Не уверен в надежном способе сделать это статически.

Вы можете использовать:

  1. AspectJ или аналогичная библиотека AOP может использоваться для инструментов классов и увеличения счетчика при создании объекта

  2. пользовательский загрузчик классов (или агент JVM, но загрузчик классов проще) может использоваться аналогично

0 голосов
/ 03 июля 2010

Вы уверены, что статический анализ - правильный инструмент для работы? Статический анализ может дать вам результат в некоторых случаях, но не во всех.

При запуске JVM под отладчиком он назначает объекты с увеличивающимися идентификаторами объектов, которые можно получить с помощью System.identityHashCode(Object o).. Этот факт можно использовать для создания тестового примера, в котором создается объект (контрольная точка), а затем вызывается метод. Если возвращенный объект в качестве идентификатора больше, чем идентификатор контрольной точки, то вы знаете, что объект был создан в методе.

Отказ от ответственности: это наблюдается поведение под отладчиком, под Windows XP.

0 голосов
/ 03 июля 2010

У меня такое ощущение, что это невозможно сделать без специально модифицированной JVM.Вот некоторые подходы ... и почему они не будут работать вообще.

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

// Bad design alert ... don't try this at home!
public class LazySingletonStringFactory {
    private String s;
    public String create(String initial) {
        if (s == null) {
            s = new String(initial);
        }
        return s;
    }
}

Чтобы статический анализатор выяснил, возвращает ли данный вызов LazySingletonStringFactory.create(...) только что созданный String, он должен вычислитьвышло, что это не было вызвано ранее.Проблема остановки говорит нам, что это теоретически невозможно в некоторых случаях, и на практике это выходит за рамки «уровня техники».

Подход IdentityHashCode может работать в однопоточномприложение, которое завершается без запуска сборщика мусора.Однако, если GC запустится, вы получите неправильные ответы.А если у вас несколько потоков, то (в зависимости от JVM) вы можете обнаружить, что объекты размещены в разных «пробелах», что приводит к последовательности создания «id» объекта, которая больше не является монотонной во всех потоках.

Code Instrumentation * Подход 1017 * работает, если вы можете изменить код интересующих вас классов, либо прямые изменения исходного кода, внедрение кода на основе аннотаций, либо путем какой-либо обработки байт-кода.Однако, в общем, вы не можете делать эти вещи для всех классов.

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

0 голосов
/ 03 июля 2010

Я не уверен, будет ли это работать для вас, но одним простым подходом было бы заполнить недавно добавленное поле 'instantiatedTime' в конструкторе объекта и сравнить его со временем вызова метода.Это предполагает, что у вас есть доступ к источнику для рассматриваемого объекта.

...