Действительно ли возможно блокировать/отклонять преобразование броска в Java?

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

http://forums.programming-designs.com/viewtopic.php?pid=3338

9
задан David Robles 7 December 2009 в 22:50
поделиться

9 ответов

Насколько мне известно, невозможно перехватить приведение типа и отклонить его (скажем, с помощью исключения ClassCastException).

Но вместо попытки отклонить набор типов можно просто используйте шаблон прокси для управления доступом к фактическому объекту GameState. Просто реализуйте прокси-класс, который реализует только GameStateInterface, и позвольте ему перенаправлять все вызовы методов в объект GameState. Теперь вместо того, чтобы передавать фактическую ссылку на объект GameState методу действия, вы передаете ее в оболочке экземпляром вашего прокси-класса.

12
ответ дан 4 December 2019 в 07:14
поделиться

В общем, вы не можете предотвратить преобразование объекта в Java. Код, который получает ссылку на ваш GameState , сможет вызывать любой незащищенный, незащищенный метод для этого объекта. Даже если бы вы могли предотвратить преобразование, оно все равно могло бы использовать отражение.

Если код Agent находится под вашим контролем, просто сохраняйте простоту и не выполняйте преобразование. Если другие пишут классы Agent , вы можете создать прокси-класс, который принимает объект GameState и реализует только методы GameStateInterface.

class GameStateProxy implements GameStateInterface {
    private GameStateInterface state;

    public GameStateProxy(GameState state) {
        this.state = state;
    }

    public int someMethodInGameStateInterface(int x) {
        return state.someMethodInGameStateInterface(x);
    }

    // other methods ...
}

Затем вы можете создать прокси и передать его следующим образом:

GameStateInterface proxy = new GameStateProxy(gameState);
int bestAction = agent.action(proxy);

код, который получает GameStateProxy , будет иметь доступ только к методам в GameStateInterface .

5
ответ дан 4 December 2019 в 07:14
поделиться

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

4
ответ дан 4 December 2019 в 07:14
поделиться

Ответ прост: «не приводите к GameState в коде вашего агента».

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

4
ответ дан 4 December 2019 в 07:14
поделиться

Если вас беспокоит изменение состояния игры агентом, создайте копию состояния и передайте ее агенту, а не реальному объекту GameState.

Запрещение приведение типов невозможно (вероятно, это неблокируемая функция спецификации языка JVM), или я никогда о ней не слышал.

2
ответ дан 4 December 2019 в 07:14
поделиться

Можно привести только к доступному типу. Сделав GameState закрытым, защищенным пакетом или защищенным, вы можете ограничить круг лиц, которые могут использовать его.

Если вы используете ненадежный код, обязательно установите диспетчер безопасности, поскольку отражение может использоваться для обхода модификаторов доступа в его absensce (cf Field.setAccessible )

1
ответ дан 4 December 2019 в 07:14
поделиться

Нет, нет способ сделать это.

С наилучшими пожеланиями,
Фабиан

0
ответ дан 4 December 2019 в 07:14
поделиться

Я не знаю, возможно ли то, что вы описываете, на Java. В других языках вы можете перегрузить операторы приведения типов и заставить их генерировать исключение или что-то в этом роде, но в Java это невозможно. Лучше всего, вероятно, сделать это одним из «многих других способов», о которых вы говорили.

0
ответ дан 4 December 2019 в 07:14
поделиться

Что мы делаем, так это выдаем банку с «заглушками», которую вы можете компилировать, но она не содержит реализации. Когда реальный продукт запускается, мы заменяем заглушки настоящей банкой.

Но тогда в нашем случае мы контролируем, где он запускается.

В нашем случае мы также делаем именно то, что вы просите. Любой класс должен запрашивать доступ к другим классам (во время выполнения). Я считаю, что это все индивидуальные реализации, и я не уверен, что она будет работать на какой-либо JVM.

Вы можете попытаться найти / запросить / любой исходный код для материала, над которым я работаю. Доступна эталонная реализация, если вы говорите, что заинтересованы в разработке для кабельных коробок, вы можете ее получить. Это называется "tru2way" или "OCAP". ссылочная реализация стека, и я думаю, что проект доступен где-то на java-сайте. Возможно, потребуется немного погуглить - и я почти уверен, что вы обнаружите, что все это делается в специальном загрузчике классов или SecurityManager.

РЕДАКТИРОВАТЬ: Я думаю, что могу ошибаться. Что мы делаем, так это создаем «разрешения» с менеджером безопасности на основе имени класса, к которому осуществляется доступ. Когда поток пытается вызвать метод в классе, мы сначала проверяем его разрешения (мы пишем код внутри «защищенного» класса), и если текущий поток не имеет разрешения, идентифицированного именем класса, он выдает исключение.

Тот же эффект, что и после, но более медленный и подробный. Но тогда мы должны запретить детям смотреть pr0n.

Редактировать 2: (Извините !! )

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

Это дает коду разрешение запрашивать у класса его общедоступные, защищенные, доступ по умолчанию (пакет) и частные поля и / или методы. Хотя код будет иметь доступ к частным и защищенным полям и именам методов, он не будет иметь доступа к данным частного / защищенного поля и не сможет вызывать какие-либо частные методы. Тем не менее вредоносный код может использовать эту информацию для более точного нацеливания атаки. Кроме того, он может вызывать любые общедоступные методы и / или получать доступ к общедоступным полям в классе. Это может быть опасно, если код обычно не может вызывать эти методы и / или получать доступ к полям, потому что он не может преобразовать объект в класс / интерфейс с этими методами и полями.

Это предоставляет коду разрешение запрашивать у класса его общедоступные, защищенные, доступ по умолчанию (пакет) и частные поля и / или методы. Хотя код будет иметь доступ к частным и защищенным полям и именам методов, он не будет иметь доступа к данным частного / защищенного поля и не сможет вызывать какие-либо частные методы. Тем не менее вредоносный код может использовать эту информацию для более точного нацеливания атаки. Кроме того, он может вызывать любые общедоступные методы и / или получать доступ к общедоступным полям в классе. Это может быть опасно, если код обычно не может вызывать эти методы и / или получать доступ к полям, потому что он не может преобразовать объект в класс / интерфейс с этими методами и полями.

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

В противном случае, как можно было бы предотвратить создание апплетами экземпляров и доступ к произвольным классам JVM? Возможно, что все «опасные» пути заблокированы так же, как мы блокируем наши материалы - путем чтения и проверки разрешений каждый раз, когда они вызываются, - но из приведенной выше цитаты кажется, что есть больше доступных, и большинство классов полностью заблокированы default.

Это меня какое-то время интересовало, но я никогда особо не разбирался в этом.

1
ответ дан 4 December 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: