___ answer1863513 ___

Die Antwort lautet einfach: "Wirf dich nicht in deinem Agent-Code an GameState!".

Alternativ kannst du das GameState-Material als privat deklarieren. Oder wenn Sie von einigen wenigen anderen Klassen darauf zugreifen müssen, deklarieren Sie es als paketgeschützt.

    
___ qstntxt ___

Ich habe den Code eines einfachen Spiels, in dem ein AgentInterface implementiert werden muss, um einen Agenten-Controller für einen der Charaktere im Spiel zu erstellen. GameState ist eine Klasse, die das GameStateInterface implementiert, und ein Objekt, das diese Schnittstelle implementiert, kann an den Agenten übergeben werden, sodass der Agent die Daten aus dem Spielzustand lesen und analysieren kann und der Agent die entsprechende Aktion (als int zurückgegeben) zurückgeben muss der Charakter sollte nehmen.

Dies ist das AgentInterface, das Agents implementieren müssen:

%Vor%

Ausführen des Spiels mit einem Agenten namens MyAgent:

%Vor%

Aber es gibt einige Informationen in GameState, auf die der Agent NICHT zugreifen darf, da dies den Controller betrügen würde. Eine Cast-Konvertierung von GameStateInterface in GameState würde es dem Agenten jedoch ermöglichen, auf Informationen zuzugreifen, die nicht im GameStateInterface definiert sind:

%Vor%

Meine Frage wäre, ist es möglich, eine Cast-Conversion zu blockieren? Ich weiß, dass Polymorphie eines der Hauptmerkmale von Java und objektorientierten Programmiersprachen ist, aber in solchen Fällen möchte ich Umwandlungen vermeiden.

Ich weiß, dass dies auf viele andere Arten gelöst werden kann, aber ich war neugierig zu wissen, ob es möglich ist, dies zu tun.

Vielen Dank im Voraus.

    
___ answer1863512 ___

Es ist nicht möglich, einen Cast zu blockieren. Sie können Ihren Spielstatus jedoch so definieren, dass er nur von einem bestimmten Ort aus erstellt werden kann. Eine Sache, die Ihnen in den Sinn kommt, wäre eine private innere Klasse, die die Schnittstelle implementiert, oder eine Factory, die eine private innere Klasseninstanz zurückgibt

    
___ answer1863510 ___

Soweit ich weiß, ist es nicht möglich, eine Typumwandlung abzufangen und zu leugnen (z. B. durch eine ClassCastException).

Aber anstatt zu versuchen, das Typecase zu leugnen, kannst du einfach das Proxymuster verwenden, um den Zugriff auf den eigentlichen GameState zu kontrollieren Objekt. Implementiere einfach eine Proxy-Klasse, die nur das GameStateInterface implementiert und es alle Methodenaufrufe an das GameState-Objekt weiterleiten lässt. Anstatt den tatsächlichen GameState-Objektverweis an die Aktionsmethode zu übergeben, übergeben Sie ihn nun von einer Instanz Ihrer Proxyklasse umschlossen.

    
___ answer1863519 ___

Wenn Sie Bedenken haben, dass der Spielstatus von einem Agenten geändert wird, erstellen Sie eine Bean-Kopie des Status und übergeben Sie diese an den Agenten und nicht an das echte GameState-Objekt.

Es ist nicht möglich, einen Cast zu verbieten (es ist wahrscheinlich eine nicht sperrbare JVM-Sprachspezifikation), oder ich habe noch nie davon gehört.

    
___ answer1863520 ___

Im Allgemeinen können Sie nicht verhindern, dass ein Objekt in Java umgewandelt wird. Der Code, der einen Verweis auf Ihre %code% erhält, kann eine nicht private, nicht geschützte Methode für dieses Objekt aufrufen. Selbst wenn Sie Casting verhindern könnten, könnte es immer noch Reflexion verwenden.

Wenn der %code% -Code unter Ihrer Kontrolle steht, halten Sie die Dinge einfach und werfen Sie sie nicht um. Wenn andere %code% -Klassen schreiben, könnten Sie eine Proxy-Klasse erstellen, die ein GameState-Objekt übernimmt und nur die Methoden von GameStateInterface implementiert.

%Vor%

Dann könnten Sie einen Proxy erstellen und es so übergeben:

%Vor%

Der Code, der ein %code% erhält, hätte nur Zugriff auf die Methoden in %code% .

    
___ answer5108831 ___

Ich habe ein gesichertes schreibgeschütztes Objekt implementiert. Wenn Sie eine schreibgeschützte Schnittstelle (keine Setter) erstellen, können Sie immer noch Methoden des reinen Objekts typisieren und darauf zugreifen. ZB Interface haben nur ein get und das Kind dieses Interface hat das Set. Wenn Sie das Objekt an die Schnittstelle übergeben, haben Sie nur den get. ABER Sie können immer noch dieses Objekt typisieren und auf alles zugreifen: (

Um dies zu vermeiden, können Sie eine Zusammensetzung erstellen, die NUR dem Ersteller der Klasse gehört. Hier ist ein Beispiel:

%Vor%

Auf diese Weise geben Sie Folgendes ein:

%Vor%

Er hat also Zugriff auf das Item-Objekt (die innere Klasse kann auf private Methoden zugreifen :)) Wenn Sie nur lesenden Zugriff auf dieses Objekt haben wollen:

%Vor%

Nun ist es absolut NICHT möglich, zu tippen, weil sie nicht vom selben Typ sind!

Hoffe, das kann jemandem helfen! (Ich würde gerne, wenn Sie Quelle nennen: P)

    
___ answer1863560 ___

Was wir tun, ist ein Jar mit "Stubs", gegen den Sie kompilieren können, aber es enthält keine Implementierung. Wenn das tatsächliche Produkt ausgeführt wird, ersetzen wir die Stubs durch ein echtes Glas.

Aber in unserem Fall kontrollieren wir, wo es läuft.

Auch in unserem Fall machen wir genau das, was Sie verlangen. Jede Klasse muss (zur Laufzeit) Zugriff auf andere Klassen anfordern. Ich glaube, das ist alles eine benutzerdefinierte Implementierung und ich bin mir nicht sicher, ob es auf einer JVM läuft.

Sie können versuchen, den Quellcode für das Zeug, an dem ich gerade arbeite, zu finden / anzufordern. Es gibt eine Referenzimplementierung, wenn Sie angeben, dass Sie an der Entwicklung von Kabelboxen interessiert sind, die Sie möglicherweise erhalten können. Es heißt die "tru2way" oder "OCAP" Referenz-Stack-Implementierung und ich denke, das Projekt ist irgendwo auf der Java-Site verfügbar. Könnte ein bisschen googlen - und ich bin mir ziemlich sicher, dass Sie alles in einem speziellen Klassenlader oder SecurityManager finden.

EDIT: Ich denke, ich könnte falsch liegen. Wir erstellen "Berechtigungen" mit dem Sicherheitsmanager basierend auf dem Namen der Klasse, auf die zugegriffen wird. Wenn ein Thread versucht, eine Methode für die Klasse aufzurufen, testen wir zuerst seine Berechtigungen (wir schreiben den Code innerhalb der Klasse "protected") und wenn der aktuelle Thread nicht über die Berechtigung verfügt, die durch den Namen der Klasse identifiziert wird, löst er ein Ausnahme.

Gleicher Effekt wie später, aber langsamer und ausführlicher. Aber dann müssen wir verhindern, dass Kinder pr0n anschauen.

Bearbeiten 2: (Entschuldigung !!)

Wenn ich auf solche Berechtigungsbeschreibungen schaue, glaube ich, dass es zumindest teilweise möglich ist:

Dadurch wird Codeberechtigung für die Abfrage einer Klasse für ihre öffentlichen, geschützten, standardmäßigen (Paket-) Zugriffs- und privaten Felder und / oder Methoden erteilt. Obwohl der Code Zugriff auf die privaten und geschützten Feld- und Methodennamen hätte, hätte er keinen Zugriff auf die Daten des privaten / geschützten Felds und könnte keine privaten Methoden aufrufen. Dennoch kann bösartiger Code diese Informationen verwenden, um einen Angriff besser zu zielen. Darüber hinaus kann es beliebige öffentliche Methoden aufrufen und / oder auf öffentliche Felder in der Klasse zugreifen. Dies könnte gefährlich sein, wenn der Code normalerweise nicht in der Lage wäre, diese Methoden aufzurufen und / oder auf die Felder zuzugreifen, da er das Objekt nicht mit diesen Methoden und Feldern an die Klasse / Schnittstelle übergeben kann.

Sonst könnten Applets daran gehindert werden, beliebige JVM-Klassen zu instanziieren und darauf zuzugreifen? Es ist möglich, dass die "Gefährlichen" Pfade auf die gleiche Art und Weise blockiert werden, wie wir unsere Sachen blockieren - indem wir die Berechtigungen jedes Mal lesen, wenn sie aufgerufen werden - aber das obige Zitat lässt den Eindruck entstehen, dass mehr verfügbar ist und die meisten Klassen komplett blockiert sind Standard.

Das hat mich eine Weile interessiert, aber ich habe mich nie wirklich darum gekümmert.

    
___ answer1863505 ___

Nein, es gibt keine Möglichkeit, dies zu tun.

Beste Wünsche,
Fabian

    
___ answer1863687 ___

Man kann nur auf einen zugänglichen Typ umwandeln. Indem Sie GameState privat, paketgeschützt oder geschützt machen, können Sie einschränken, wer darauf casten darf.

Wenn Sie nicht vertrauenswürdigen Code ausführen, müssen Sie einen Sicherheitsmanager installieren, da die Reflektion dazu verwendet werden kann, Zugriffsmodifizierer in der Datei absensce zu umgehen (siehe Feld.setAccessible )

    
___ tag123java ___ Java (nicht zu verwechseln mit JavaScript oder JScript oder JS) ist eine universelle objektorientierte Programmiersprache, die für die Verwendung in Verbindung mit der Java Virtual Machine (JVM) entwickelt wurde. "Java-Plattform" ist der Name für ein Computersystem, auf dem Tools zum Entwickeln und Ausführen von Java-Programmen installiert sind. Verwenden Sie dieses Tag für Fragen, die sich auf die Java-Programmiersprache oder Java-Plattform-Tools beziehen. ___ tag123casting ___ Casting ist ein Prozess, bei dem ein Objekttyp explizit in einen anderen Typ konvertiert wird, wenn die Konvertierung zulässig ist. Dieser Prozess könnte zu einer Wertänderung führen. ___ answer1863507 ___

Ich weiß nicht, ob das, was Sie beschreiben, in Java möglich ist. In anderen Sprachen können Sie typecast-Operatoren überlasten und sie eine Exception oder etwas auslösen lassen, aber das ist in Java nicht möglich. Ihre beste Wette ist wahrscheinlich, es auf eine der "vielen anderen Arten" zu tun, über die Sie gesprochen haben.

    
___

8

Ich habe den Code eines einfachen Spiels, in dem ein AgentInterface implementiert werden muss, um einen Agenten-Controller für einen der Charaktere im Spiel zu erstellen. GameState ist eine Klasse, die das GameStateInterface implementiert, und ein Objekt, das diese Schnittstelle implementiert, kann an den Agenten übergeben werden, sodass der Agent die Daten aus dem Spielzustand lesen und analysieren kann und der Agent die entsprechende Aktion (als int zurückgegeben) zurückgeben muss der Charakter sollte nehmen.

Dies ist das AgentInterface, das Agents implementieren müssen:

%Vor%

Ausführen des Spiels mit einem Agenten namens MyAgent:

%Vor%

Aber es gibt einige Informationen in GameState, auf die der Agent NICHT zugreifen darf, da dies den Controller betrügen würde. Eine Cast-Konvertierung von GameStateInterface in GameState würde es dem Agenten jedoch ermöglichen, auf Informationen zuzugreifen, die nicht im GameStateInterface definiert sind:

%Vor%

Meine Frage wäre, ist es möglich, eine Cast-Conversion zu blockieren? Ich weiß, dass Polymorphie eines der Hauptmerkmale von Java und objektorientierten Programmiersprachen ist, aber in solchen Fällen möchte ich Umwandlungen vermeiden.

Ich weiß, dass dies auf viele andere Arten gelöst werden kann, aber ich war neugierig zu wissen, ob es möglich ist, dies zu tun.

Vielen Dank im Voraus.

    
David Robles 07.12.2009, 22:50
quelle

10 Antworten

12

Soweit ich weiß, ist es nicht möglich, eine Typumwandlung abzufangen und zu leugnen (z. B. durch eine ClassCastException).

Aber anstatt zu versuchen, das Typecase zu leugnen, kannst du einfach das Proxymuster verwenden, um den Zugriff auf den eigentlichen GameState zu kontrollieren Objekt. Implementiere einfach eine Proxy-Klasse, die nur das GameStateInterface implementiert und es alle Methodenaufrufe an das GameState-Objekt weiterleiten lässt. Anstatt den tatsächlichen GameState-Objektverweis an die Aktionsmethode zu übergeben, übergeben Sie ihn nun von einer Instanz Ihrer Proxyklasse umschlossen.

    
Simon Lehmann 07.12.2009, 22:56
quelle
4

Es ist nicht möglich, einen Cast zu blockieren. Sie können Ihren Spielstatus jedoch so definieren, dass er nur von einem bestimmten Ort aus erstellt werden kann. Eine Sache, die Ihnen in den Sinn kommt, wäre eine private innere Klasse, die die Schnittstelle implementiert, oder eine Factory, die eine private innere Klasseninstanz zurückgibt

    
Steve B. 07.12.2009 22:57
quelle
4

Die Antwort lautet einfach: "Wirf dich nicht in deinem Agent-Code an GameState!".

Alternativ kannst du das GameState-Material als privat deklarieren. Oder wenn Sie von einigen wenigen anderen Klassen darauf zugreifen müssen, deklarieren Sie es als paketgeschützt.

    
Anon. 07.12.2009 22:57
quelle
4

Im Allgemeinen können Sie nicht verhindern, dass ein Objekt in Java umgewandelt wird. Der Code, der einen Verweis auf Ihre GameState erhält, kann eine nicht private, nicht geschützte Methode für dieses Objekt aufrufen. Selbst wenn Sie Casting verhindern könnten, könnte es immer noch Reflexion verwenden.

Wenn der Agent -Code unter Ihrer Kontrolle steht, halten Sie die Dinge einfach und werfen Sie sie nicht um. Wenn andere Agent -Klassen schreiben, könnten Sie eine Proxy-Klasse erstellen, die ein GameState-Objekt übernimmt und nur die Methoden von GameStateInterface implementiert.

%Vor%

Dann könnten Sie einen Proxy erstellen und es so übergeben:

%Vor%

Der Code, der ein GameStateProxy erhält, hätte nur Zugriff auf die Methoden in GameStateInterface .

    
Jay Conrod 07.12.2009 22:58
quelle
2

Wenn Sie Bedenken haben, dass der Spielstatus von einem Agenten geändert wird, erstellen Sie eine Bean-Kopie des Status und übergeben Sie diese an den Agenten und nicht an das echte GameState-Objekt.

Es ist nicht möglich, einen Cast zu verbieten (es ist wahrscheinlich eine nicht sperrbare JVM-Sprachspezifikation), oder ich habe noch nie davon gehört.

    
Nick Hristov 07.12.2009 22:58
quelle
2

Ich habe ein gesichertes schreibgeschütztes Objekt implementiert. Wenn Sie eine schreibgeschützte Schnittstelle (keine Setter) erstellen, können Sie immer noch Methoden des reinen Objekts typisieren und darauf zugreifen. ZB Interface haben nur ein get und das Kind dieses Interface hat das Set. Wenn Sie das Objekt an die Schnittstelle übergeben, haben Sie nur den get. ABER Sie können immer noch dieses Objekt typisieren und auf alles zugreifen: (

Um dies zu vermeiden, können Sie eine Zusammensetzung erstellen, die NUR dem Ersteller der Klasse gehört. Hier ist ein Beispiel:

%Vor%

Auf diese Weise geben Sie Folgendes ein:

%Vor%

Er hat also Zugriff auf das Item-Objekt (die innere Klasse kann auf private Methoden zugreifen :)) Wenn Sie nur lesenden Zugriff auf dieses Objekt haben wollen:

%Vor%

Nun ist es absolut NICHT möglich, zu tippen, weil sie nicht vom selben Typ sind!

Hoffe, das kann jemandem helfen! (Ich würde gerne, wenn Sie Quelle nennen: P)

    
jrl 24.02.2011 18:24
quelle
1

Was wir tun, ist ein Jar mit "Stubs", gegen den Sie kompilieren können, aber es enthält keine Implementierung. Wenn das tatsächliche Produkt ausgeführt wird, ersetzen wir die Stubs durch ein echtes Glas.

Aber in unserem Fall kontrollieren wir, wo es läuft.

Auch in unserem Fall machen wir genau das, was Sie verlangen. Jede Klasse muss (zur Laufzeit) Zugriff auf andere Klassen anfordern. Ich glaube, das ist alles eine benutzerdefinierte Implementierung und ich bin mir nicht sicher, ob es auf einer JVM läuft.

Sie können versuchen, den Quellcode für das Zeug, an dem ich gerade arbeite, zu finden / anzufordern. Es gibt eine Referenzimplementierung, wenn Sie angeben, dass Sie an der Entwicklung von Kabelboxen interessiert sind, die Sie möglicherweise erhalten können. Es heißt die "tru2way" oder "OCAP" Referenz-Stack-Implementierung und ich denke, das Projekt ist irgendwo auf der Java-Site verfügbar. Könnte ein bisschen googlen - und ich bin mir ziemlich sicher, dass Sie alles in einem speziellen Klassenlader oder SecurityManager finden.

EDIT: Ich denke, ich könnte falsch liegen. Wir erstellen "Berechtigungen" mit dem Sicherheitsmanager basierend auf dem Namen der Klasse, auf die zugegriffen wird. Wenn ein Thread versucht, eine Methode für die Klasse aufzurufen, testen wir zuerst seine Berechtigungen (wir schreiben den Code innerhalb der Klasse "protected") und wenn der aktuelle Thread nicht über die Berechtigung verfügt, die durch den Namen der Klasse identifiziert wird, löst er ein Ausnahme.

Gleicher Effekt wie später, aber langsamer und ausführlicher. Aber dann müssen wir verhindern, dass Kinder pr0n anschauen.

Bearbeiten 2: (Entschuldigung !!)

Wenn ich auf solche Berechtigungsbeschreibungen schaue, glaube ich, dass es zumindest teilweise möglich ist:

Dadurch wird Codeberechtigung für die Abfrage einer Klasse für ihre öffentlichen, geschützten, standardmäßigen (Paket-) Zugriffs- und privaten Felder und / oder Methoden erteilt. Obwohl der Code Zugriff auf die privaten und geschützten Feld- und Methodennamen hätte, hätte er keinen Zugriff auf die Daten des privaten / geschützten Felds und könnte keine privaten Methoden aufrufen. Dennoch kann bösartiger Code diese Informationen verwenden, um einen Angriff besser zu zielen. Darüber hinaus kann es beliebige öffentliche Methoden aufrufen und / oder auf öffentliche Felder in der Klasse zugreifen. Dies könnte gefährlich sein, wenn der Code normalerweise nicht in der Lage wäre, diese Methoden aufzurufen und / oder auf die Felder zuzugreifen, da er das Objekt nicht mit diesen Methoden und Feldern an die Klasse / Schnittstelle übergeben kann.

Sonst könnten Applets daran gehindert werden, beliebige JVM-Klassen zu instanziieren und darauf zuzugreifen? Es ist möglich, dass die "Gefährlichen" Pfade auf die gleiche Art und Weise blockiert werden, wie wir unsere Sachen blockieren - indem wir die Berechtigungen jedes Mal lesen, wenn sie aufgerufen werden - aber das obige Zitat lässt den Eindruck entstehen, dass mehr verfügbar ist und die meisten Klassen komplett blockiert sind Standard.

Das hat mich eine Weile interessiert, aber ich habe mich nie wirklich darum gekümmert.

    
Bill K 07.12.2009 23:09
quelle
1

Man kann nur auf einen zugänglichen Typ umwandeln. Indem Sie GameState privat, paketgeschützt oder geschützt machen, können Sie einschränken, wer darauf casten darf.

Wenn Sie nicht vertrauenswürdigen Code ausführen, müssen Sie einen Sicherheitsmanager installieren, da die Reflektion dazu verwendet werden kann, Zugriffsmodifizierer in der Datei absensce zu umgehen (siehe Feld.setAccessible )

    
meriton 07.12.2009 23:46
quelle
0

Nein, es gibt keine Möglichkeit, dies zu tun.

Beste Wünsche,
Fabian

    
halfdan 07.12.2009 22:54
quelle
0

Ich weiß nicht, ob das, was Sie beschreiben, in Java möglich ist. In anderen Sprachen können Sie typecast-Operatoren überlasten und sie eine Exception oder etwas auslösen lassen, aber das ist in Java nicht möglich. Ihre beste Wette ist wahrscheinlich, es auf eine der "vielen anderen Arten" zu tun, über die Sie gesprochen haben.

    
iandisme 07.12.2009 22:55
quelle

Tags und Links

Django: Verwenden von Annotate, Count und Distinct in einem Queryset ___ answer1956028 ___

Normalerweise mache ich:

%Vor%     
___ answer39814493 ___

Bei Bedarf schnelle 3-Version:

%Vor%     
___ answer1960998 ___

Ok, tut mir leid, als wäre ich durch meinen Code gegangen.

Ich habe den Indikator folgendermaßen beendet:

%Vor%

Nach einem Durchlauf wurde der activityIndicator vollständig entfernt.

    
___ answer13950480 ___

Diese Frage ist sehr nützlich. Aber eine Sache, die in der Antwort fehlt, ist, dass alles, was lange braucht, in einem separaten Thread ausgeführt werden muss, nicht die UIActivityIndicatorView. Auf diese Weise reagiert es nicht mehr auf die Benutzeroberfläche.

%Vor%     
___ tag123iphone ___ Verwenden Sie diesen Tag NICHT, es sei denn, Sie wenden sich speziell an Apple's iPhone und / oder iPod touch. Verwenden Sie für nicht hardwareabhängige Fragen das Tag [ios]. Weitere zu betrachtende Tags sind [xcode] (aber nur, wenn es sich um die IDE selbst handelt), [swift], [objective-c] oder [cacao-touch] (aber nicht [cocoa]). Bitte verzichten Sie auf Fragen zum iTunes App Store oder zu iTunes Connect. Wenn Sie C # verwenden, markieren Sie mit [mono]. ___ tag123uactivityindicatorview ___ Unter iOS können Sie einen Aktivitätsindikator verwenden, um anzuzeigen, dass eine Aufgabe ausgeführt wird. Eine Aktivitätsanzeige erscheint als "Zahnrad", das sich dreht oder stoppt. Sie steuern, wann ein Aktivitätsindikator animiert wird, indem Sie die Methoden startAnimating und stopAnimating aufrufen. Um den Aktivitätsindikator beim Beenden der Animation automatisch auszublenden, legen Sie die Eigenschaft "hidesWhenStopped" auf YES fest. ___ answer18418439 ___

Alle UI-Elemente müssen sich im Haupt-Thread befinden

%Vor%

dann:

%Vor%     
___ qstntxt ___

Wenn ich startAnimating für eine UIActivityIndicatorView aufruft, wird sie nicht gestartet. Warum ist das?

[Dies ist eine Blog-artige selbstbeantwortete Frage. Die Lösung unten funktioniert für mich, aber vielleicht gibt es andere, die besser sind?]

    
___ answer1850228 ___

Wenn Sie Code wie folgt schreiben:

%Vor%

Sie erteilen der Benutzeroberfläche keine Zeit, um den Aktivitätsindikator tatsächlich zu starten und zu stoppen, da sich Ihre gesamte Berechnung auf den Hauptthread bezieht. Eine Lösung besteht darin, startAnimating in einem separaten Thread aufzurufen:

%Vor%

Oder Sie könnten Ihre Berechnung in einen separaten Thread einfügen und warten, bis sie beendet ist, bevor Sie stopAnimation aufrufen.

    
___