Существует ли API / Инструмент, который реализует «определяемые пользователем типы значений» в JVM? - PullRequest
3 голосов
/ 26 ноября 2011

Если у меня есть простой тип данных, то, что может быть представлено одним примитивным значением, например, int, например, счетчик, и мой класс является неизменяемым (это важно), я хотел бы определить все бизнеслогика, в том числе предварительные условия, такие как «не может быть отрицательным», так что ее использование безопасно, и оно может содержать только действительные данные.С такими типами вы не можете случайно добавить количество колес к количеству пассажиров (если они разные типы счетчиков), но вы могли бы, если бы оба были просто целыми числами.

Так что мне бы хотелось, чтобы был способ аннотировать эти типы как «встроенные», чтобы ссылки экземпляра были заменены на значение состояния, а вызовы методов экземпляра были заменены вызовами статических методов, принимающих или получающихсостояние, которое JIT может также включить.Одним из ограничений является то, что не все сайты использования могут быть заменены, как, например, включение одного из них в список Java.Но массивы могут быть эффективно заменены.

Таким образом, основное преимущество будет состоять в том, чтобы «удалить накладные расходы на объект», а также косвенно создать объект и затраты на сборку мусора, сохраняя при этом ваш код максимально безопасным.

JIT делает метод встраивания для нас, и это нормально в большинстве случаев, но он не устраняет (по крайней мере, до сих пор) накладные расходы на объект, поэтому состояние объектов обычно создается с примитивными типами, а не с бизнесом.-моделировать конкретные типы.Специфичные для бизнес-модели типы безопаснее в использовании и следуют принципу СУХОЙ;Вы должны определить свои предварительные условия только один раз.Но цена, которую вы должны заплатить за такое простое, во многих случаях просто слишком высока.

В идеале я бы предпочел инструмент уровня байтового кода, время компиляции или время загрузки, потому что я делаю смешанную Java-Scala-кодирование.

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

Последнее замечание: пожалуйста, не проповедуйте мне, что «объекты дешевы».Я занимаюсь Java в течение 10 лет и отвечаю за профилирование JVM в моей команде, по крайней мере, последние 6 лет, поэтому я до боли знаю, сколько стоят объекты.

1 Ответ

4 голосов
/ 26 ноября 2011

То, о чем вы говорите, звучит очень похоже на типы значений - типы, которые следует рассматривать как «прямые» значения, а не как объекты (доступ через ссылки), как примитивные типы.

Java не имеет определяемых пользователем типов значений и, скорее всего, не получит их в новой версии в ближайшее время (возможно, в Java 9 или даже позже).Насколько я знаю, JVM или JIT также не обрабатывают автоматически ваши объекты как типы значений («полное встраивание класса»).

Обратите внимание, что в C # есть определяемые пользователем типы значений .

Однако использование методов уже может сделать ваш код достаточно эффективным.Учтите это:

class MyValue {
    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

Метод getter и setter будет встроен JVM при вызове их, поэтому вызов этих методов так же эффективен, как и прямой доступ к переменной-члену value класса.Однако экземпляр MyValue будет занимать больше памяти, чем int, поскольку объекты Java имеют некоторые неизбежные накладные расходы (например, вы можете синхронизировать любой объект в Java, поэтому каждый объект должен иметь связанную с ним блокировку -эта блокировка является частью состояния объекта).

Поскольку в Java отсутствуют типы значений, невозможно создать массив объектов, которые гарантированно будут последовательно размещаться в памяти.Массив с типом элемента, который является не примитивным типом, на самом деле является массивом ссылок на объекты, и объекты, на которые указывают эти ссылки, в принципе могут быть разбросаны по всей куче.Это нехорошо для производительности для определенных операций (например, если вы выполняете итерацию по массиву, кэш ЦП работает наиболее эффективно, если схема доступа к памяти предсказуема - она ​​будет менее эффективной, если объекты разбросаны в случайных местах).

Об объектах, которые дешевы: одна оптимизация в недавних JDK - это escape анализ , что приведет к тому, что временные объекты, локальные для метода, будут размещены в стеке, а не в куче, чтобы освободить выделенную памятьявляется по сути бесплатным (сборщик мусора не должен иметь дело с объектом).

...