Plugin-Erstellung/Java/Reflexion in Java: Unterschied zwischen den Versionen
(7 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 225: | Zeile 225: | ||
== Beispiel 4 == | == Beispiel 4 == | ||
=== MethodCaller Klasse === | === MethodCaller Klasse === | ||
Beispiel für eine MethodCaller Klasse. | |||
In dieser Version der MethodCaller-Klasse, werden die Methoden und Parameter aus der Player-Klasse der Plugin-API aufgerufen. | |||
Beim Aufruf der invoke-Methode wird der Rückgabewert der aufgerufenen Methode als '''Object''' zurückgegeben. | |||
<syntaxhighlight lang="java" line start="1"> | <syntaxhighlight lang="java" line start="1"> | ||
// ... | import java.lang.reflect.Method; | ||
import java.lang.reflect.Type; | |||
import net.risingworld.api.objects.Player; | |||
public class MethodCaller | |||
{ | |||
// Startet eine Methode mit dem angegebenen Namen | |||
// und den optionalen Argumenten auf dem übergebenen Player-Objekt | |||
public Object startMethod(Player player, String methodName, Object... args) throws Exception | |||
{ | |||
// Holt sich die Klasse, in der die Methode definiert ist | |||
Class<?> targetClass = player.getClass(); | |||
// Holt sich die Methode basierend auf dem Namen und den Parametertypen | |||
Class<?>[] parameterTypes = new Class[args.length]; | |||
for (int i = 0; i < args.length; i++) { | |||
parameterTypes[i] = args[i].getClass(); | |||
} | |||
Method method = targetClass.getDeclaredMethod(methodName, parameterTypes); | |||
// Rufe die Methode auf und gib den Rückgabewert zurück | |||
return method.invoke(player, args); | |||
} | |||
// Überladene Methode, die auch String-Argumente akzeptiert | |||
public Object startMethod(Player player, String methodName, String... args) throws Exception | |||
{ | |||
// Konvertiere String-Argumente in Object-Array | |||
Object[] objArgs = new Object[args.length]; | |||
for (int i = 0; i < args.length; i++) { | |||
objArgs[i] = args[i]; | |||
} | |||
// Rufe die ursprüngliche startMethod auf | |||
return startMethod(player, methodName, objArgs); | |||
} | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
In dieser erweiterten Version der MethodCaller-Klasse gibt es auch eine Überladung der startMethod-Methode, die auch String-Argumente akzeptiert. Diese Methode konvertiert die String-Argumente in ein Object-Array und ruft dann die ursprüngliche startMethod-Methode auf. | |||
=== MyPluginClass Klasse === | |||
Hier ist ein Beispiel, wie Reflexion in einer onPlayerCommand Methode verwendet werden kann, um Methoden aus der [https://javadoc.rising-world.net/latest/net/risingworld/api/objects/Player.html Player Klasse] aufzurufen: | |||
<syntaxhighlight lang="java" line start="39"> | |||
@EventMethod | |||
public void onPlayerCommand(PlayerCommandEvent event) | |||
{ | |||
//diese Methode wird aufgerufen, wenn das "PlayerCommandEvent" ausgelöst wird | |||
MethodCaller caller = new MethodCaller(); | |||
//Befehl durch Leerzeichen Teilen | |||
String[] cmd = event.getCommand().split(" "); | |||
//Spieler, der den Befehl ausgeführt hat | |||
Player player = event.getPlayer(); | |||
String sPlayerName = player.getName(); | |||
int iDbID = 0; | |||
Object oReturn = null; | |||
try | |||
{ | |||
iDbID = (int)caller.startMethod(player, "getDbID"); | |||
player.sendTextMessage("Player "+sPlayerName+" DbID = "+iDbID); | |||
} | |||
catch (Exception e) | |||
{ | |||
} | |||
// Wenn der Spieler "/call" eingibt | |||
if (cmd[0].equalsIgnoreCase("/call")) | |||
{ | |||
if (cmd.length == 2) | |||
{ | |||
try | |||
{ | |||
oReturn = caller.startMethod(player, cmd[1]); | |||
player.sendTextMessage("Call "+cmd[1]+" return = "+oReturn.toString()); | |||
} | |||
catch (Exception exc) | |||
{ | |||
player.sendTextMessage("Call "+cmd[1]+": \r\n"+exc.toString()); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
== Siehe auch == | == Siehe auch == | ||
* [https://javadoc.rising-world.net/latest/net/risingworld/api/package-summary.html JavaDoc RW: API Packages] | * [https://javadoc.rising-world.net/latest/net/risingworld/api/package-summary.html JavaDoc RW: API Packages] | ||
* [[Plugin-Erstellung]] | * [[Plugin-Erstellung]] | ||
Zeile 239: | Zeile 325: | ||
* [https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html Oracle docs: Invoking Methods] | * [https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html Oracle docs: Invoking Methods] | ||
=== Forum === | |||
* [https://forum.rising-world.net/thread/12493-getting-started/ Rising World Forum: Getting started] | |||
* [https://forum.rising-world.net/thread/4757-create-a-plugin/ Rising World Forum: Create a Plugin] | |||
* [https://forum.rising-world.net/board/45-plugins-neue-version/ Rising World Forum: Plugins (Neue Version)] | |||
=== Kategorien === | |||
{| style="margin:auto; width:100%;" class="nix_wikitable" | |||
|- style="vertical-align: top;" | |||
| style="width:50%" | '''Tutorial Kategorien''' | |||
<categorytree mode="categories" hideroot=off showcount=on>Plugin-API</categorytree> | |||
| style="width:50%" | '''Plugin-Erstellung''' | |||
<categorytree mode="categories" hideroot=off showcount=on>Plugin-Erstellung</categorytree> | |||
|} | |||
[[Kategorie:Java|Reflexion]] | [[Kategorie:Java|Reflexion]] | ||
[[Kategorie:Java-Codeschnipsel|Reflexion]] | [[Kategorie:Java-Codeschnipsel|Reflexion]] | ||
[[Kategorie:Tutorial]] | [[Kategorie:Tutorial]] |
Aktuelle Version vom 1. November 2024, 11:05 Uhr
* Diese Seite ist in Bearbeitung * This page is in progress *
Bitte schaue später noch einmal vorbei, um weitere Änderungen zu erfahren.
Please check back later for additional changes.
|
Reflexion ist eine leistungsstarke Funktion in Java, die es ermöglicht, zur Laufzeit auf Klassen, Methoden und Felder zuzugreifen und diese zu manipulieren. In diesem Artikel werden die Grundlagen der Reflexion in Java erläutert, insbesondere im Kontext von Plugins für das Spiel Rising World.
Grundlagen der Reflexion
Reflexion in Java ermöglicht es, zur Laufzeit auf die Struktur, Methoden und das Verhalten von Klassen zuzugreifen, ohne dass deren Namen zur Compilezeit bekannt sein müssen. Dies bietet eine flexible Möglichkeit, Klassen dynamisch zu untersuchen ...
Import
Es muss zuerst das folgende Paket importieren verwenden, um die Reflexions-API zu verwenden.
import java.lang.reflect.*
- es importiert alle Klassen, die in der Reflexions-API enthalten sind.
oder
import java.lang.reflect.Method;
- es importiert nur die Klasse Method
Beispiel 1
Ein Szenario in Rising World Plugins ist das dynamische Aufrufen von Methoden basierend auf Spieleraktionen.
MethodCaller Klasse
Beispiel für eine einfache MethodCaller Klasse
import java.lang.reflect.Method;
public class MethodCaller
{
public void startMethod(String methodName) throws Exception
{
// Holen Sie sich die Klasse, in der die Methode definiert ist
Class<?> targetClass = this.getClass();
// Holen Sie sich die Methode basierend auf dem Namen
Method method = targetClass.getDeclaredMethod(methodName);
// Rufe die Methode auf
method.invoke(this);
}
public void method1()
{
System.out.println("Methode 1 wurde aufgerufen");
}
public void method2()
{
System.out.println("Methode 2 wurde aufgerufen");
}
}
Klassenobjekt
Reflektion kann auf dem Class-Objekt ausgeführt werden. Ein Klassenobjekt kann auf mehrere Arten erstellt werden.
Class<?> targetClass = this.getClass();
Class targetClass = Class.forName("Klassenname");
Class targetClass = MethodCaller.class;
MethodCaller instantCls = new MethodCaller();
Class targetClass = instantCls.getClass();
MyPluginClass Klasse
Hier ist ein Beispiel, wie Reflexion in einer MyPluginClass Klasse verwendet werden kann, um Methoden basierend auf Spielerbefehlen aufzurufen:
package net.mypackage.mainerstesplugin;
import net.risingworld.api.Plugin;
import net.risingworld.api.events.EventMethod;
import net.risingworld.api.events.Listener;
import net.risingworld.api.objects.Player;
import net.risingworld.api.events.player.PlayerConnectEvent;
import net.risingworld.api.events.player.PlayerSpawnEvent;
import net.risingworld.api.events.player.PlayerCommandEvent;
public class MyPluginClass extends Plugin implements Listener
{
@Override
public void onEnable()
{
registerEventListener(this);
System.out.println(this.getName() + ": ist geladen");
}
@Override
public void onDisable()
{
// Plugin wurde entladen
}
@EventMethod
public void onPlayerConnectEvent(PlayerConnectEvent event)
{
System.out.println(this.getName() + ": Player Connect");
}
@EventMethod
public void onPlayerSpawn(PlayerSpawnEvent event)
{
Player player = event.getPlayer();
player.sendTextMessage("Player "+player.getName()+" Spawn");
}
@EventMethod
public void onPlayerCommand(PlayerCommandEvent event)
{
//diese Methode wird aufgerufen, wenn das "PlayerCommandEvent" ausgelöst wird
MethodCaller caller = new MethodCaller();
//Befehl durch Leerzeichen Teilen
String[] cmd = event.getCommand().split(" ");
//Spieler, der den Befehl ausgeführt hat
Player player = event.getPlayer();
// Wenn der Spieler "/call" eingibt
if (cmd[0].equalsIgnoreCase("/call"))
{
if (cmd.length == 2)
{
try
{
caller.startMethod(cmd[1]);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
Beispiel 2
MethodCaller Klasse
Beispiel für eine MethodCaller Klasse.
import java.lang.reflect.Method;
import java.lang.reflect.Type;
public class MethodCaller
{
public void startMethod(String methodName) throws Exception
{
startMethod(methodName, new Object[0]);
}
public void startMethod(String methodName, Object... args) throws Exception
{
// Holt sich die Klasse, in der die Methode definiert ist
Class<?> targetClass = this.getClass();
// Holt sich die Methode basierend auf dem Namen und den Parametertypen
Class<?>[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i].getClass();
}
Method method = targetClass.getDeclaredMethod(methodName, parameterTypes);
// Rufe die Methode auf
method.invoke(this, args);
}
public void method1()
{
System.out.println("Methode 1 wurde aufgerufen");
}
public void method2()
{
System.out.println("Methode 2 wurde aufgerufen");
}
public void method3(boolean isTrue)
{
System.out.println("Methode 3 wurde mit "+ isTrue +" aufgerufen");
}
}
MethodCaller caller = new MethodCaller();
caller.startMethod("method1"); // Aufruf von method1
caller.startMethod("method2"); // Aufruf von method2
caller.startMethod("method3", true); // Aufruf von method3 mit isTrue = true
Beispiel 3
MethodCaller Klasse
Beispiel für eine MethodCaller Klasse.
In dieser Version der MethodCaller-Klasse, werden die Methoden und Parameter aus der Player-Klasse der Plugin-API aufgerufen. Es werden keine Werte zurückgegeben.
Es wird Class targetClass = player.getClass();
verwendet, um die Klasse des player-Objekts zu erhalten. Die Methode startMethod akzeptiert auch eine variable Anzahl von Argumenten, um Parameter an die aufgerufene Methode zu übergeben.
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import net.risingworld.api.objects.Player;
public class MethodCaller
{
// Startet eine Methode mit dem angegebenen Namen
// und den optionalen Argumenten auf dem übergebenen Player-Objekt
public void startMethod(Player player, String methodName, Object... args) throws Exception
{
// Holt sich die Klasse, in der die Methode definiert ist
Class targetClass = player.getClass();
// Holt sich die Methode basierend auf dem Namen und den Parametertypen
Class[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i].getClass();
}
Method method = targetClass.getDeclaredMethod(methodName, parameterTypes);
// Rufe die Methode auf
method.invoke(player, args);
}
}
Die Methode startMethod verwendet Reflexion, um die entsprechende Methode basierend auf ihrem Namen und den Parametertypen zu finden und aufzurufen. Die Parametertypen werden aus den übergebenen Argumenten extrahiert, um die richtige Überladung der Methode zu identifizieren.
Beispiel 4
MethodCaller Klasse
Beispiel für eine MethodCaller Klasse. In dieser Version der MethodCaller-Klasse, werden die Methoden und Parameter aus der Player-Klasse der Plugin-API aufgerufen. Beim Aufruf der invoke-Methode wird der Rückgabewert der aufgerufenen Methode als Object zurückgegeben.
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import net.risingworld.api.objects.Player;
public class MethodCaller
{
// Startet eine Methode mit dem angegebenen Namen
// und den optionalen Argumenten auf dem übergebenen Player-Objekt
public Object startMethod(Player player, String methodName, Object... args) throws Exception
{
// Holt sich die Klasse, in der die Methode definiert ist
Class<?> targetClass = player.getClass();
// Holt sich die Methode basierend auf dem Namen und den Parametertypen
Class<?>[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i].getClass();
}
Method method = targetClass.getDeclaredMethod(methodName, parameterTypes);
// Rufe die Methode auf und gib den Rückgabewert zurück
return method.invoke(player, args);
}
// Überladene Methode, die auch String-Argumente akzeptiert
public Object startMethod(Player player, String methodName, String... args) throws Exception
{
// Konvertiere String-Argumente in Object-Array
Object[] objArgs = new Object[args.length];
for (int i = 0; i < args.length; i++) {
objArgs[i] = args[i];
}
// Rufe die ursprüngliche startMethod auf
return startMethod(player, methodName, objArgs);
}
}
In dieser erweiterten Version der MethodCaller-Klasse gibt es auch eine Überladung der startMethod-Methode, die auch String-Argumente akzeptiert. Diese Methode konvertiert die String-Argumente in ein Object-Array und ruft dann die ursprüngliche startMethod-Methode auf.
MyPluginClass Klasse
Hier ist ein Beispiel, wie Reflexion in einer onPlayerCommand Methode verwendet werden kann, um Methoden aus der Player Klasse aufzurufen:
@EventMethod
public void onPlayerCommand(PlayerCommandEvent event)
{
//diese Methode wird aufgerufen, wenn das "PlayerCommandEvent" ausgelöst wird
MethodCaller caller = new MethodCaller();
//Befehl durch Leerzeichen Teilen
String[] cmd = event.getCommand().split(" ");
//Spieler, der den Befehl ausgeführt hat
Player player = event.getPlayer();
String sPlayerName = player.getName();
int iDbID = 0;
Object oReturn = null;
try
{
iDbID = (int)caller.startMethod(player, "getDbID");
player.sendTextMessage("Player "+sPlayerName+" DbID = "+iDbID);
}
catch (Exception e)
{
}
// Wenn der Spieler "/call" eingibt
if (cmd[0].equalsIgnoreCase("/call"))
{
if (cmd.length == 2)
{
try
{
oReturn = caller.startMethod(player, cmd[1]);
player.sendTextMessage("Call "+cmd[1]+" return = "+oReturn.toString());
}
catch (Exception exc)
{
player.sendTextMessage("Call "+cmd[1]+": \r\n"+exc.toString());
}
}
}
}
}
Siehe auch
- JavaDoc RW: API Packages
- Plugin-Erstellung
- Eclipse Entwicklungsumgebung (Plugin Tutorial)
- Wiki Kategorie: "Java"
- Oracle docs: Invoking Methods
Forum
- Rising World Forum: Getting started
- Rising World Forum: Create a Plugin
- Rising World Forum: Plugins (Neue Version)
Kategorien
Tutorial Kategorien
Tutorial (2 S) |
Plugin-Erstellung
|