3

コマンドでテレポートポイントを保存するために、私はHashMap

public HashMap<Player, Location> mapHomes = new HashMap<>();

これは次のようにアクセスされます:

if(cmd.getName().equalsIgnoreCase("sethome")){
    Location loc = player.getLocation();
    mapHomes.put(player, loc);
    sender.sendMessage("Home set !");
    return true;
}
if(cmd.getName().equalsIgnoreCase("home")){
    Location loc1 = mapHomes.get(player);
    player.teleport(loc1);
    sender.sendMessage("Teleported to home");
    return true;
}
return false;

これらの設定は再起動時に保持する必要があるため、saveメソッドを実装しました。

public void save(HashMap<Player,Location> mapHome, String path) throws NotSerializableException{
    try{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
        oos.writeObject(mapHome);
        oos.flush();
        oos.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}

しかし、それは機能していません。投げNotSerializableExceptionます。

主な問題はシリアライズ可能なタイプであるPlayerと思いますLocationが、これを書くにはどうすればよいHashMapですか?

4

6 に答える 6

2

HashMapすでにSerializableです。

問題は、マップ内のオブジェクトがそうではないことです。そのため、それらもシリアル化可能にする必要があります。

public class SerializedPlayer extends Player implements Serializable {
    public SerializedPlayer() {}
    public SerializedPlayer(Player playerToClone) {
        this.setField1(playerToClone.getField1());
        // Set all the fields
    }
}

マップに追加する場合:

map.put(new SerializedPlayer(player), new SerializedLocation(location));
于 2012-08-10T08:05:47.743 に答える
1

NotSerializableExceptionインスタンスにインターフェースが必要な場合にスローされSerializableます。

class YourClass implements Serializable {
    // ...
}
于 2012-08-10T08:10:22.980 に答える
0
class Player implements Serializable {}

class Location implements Serializable {}

Serializableインターフェイスを実装するオブジェクトのみをシリアル化できることを忘れないでください。したがって、あなたPlayerLocationクラスもインターフェースを実装する必要があります。

于 2012-08-10T08:02:24.387 に答える
0

私はあなたがHashMap<Player, Location>ファイルに書いていると思います。

あなたがする必要があるのはあなたPlayerLocationクラスをシリアライズ可能にすることです。

public class Player implements java.io.Serializable {
    // ...
}

public class Location implements java.io.Serializable {
    // ...
}

HashMapすでにシリアル化可能です。

于 2012-08-10T08:05:36.227 に答える
0

シリアル化するには、このクラスLocationを使用することをお勧めします。私はそれを自分で書いたので、コードのクレジットをお願いします。

package com.github.JamesNorris.Class;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;

/**
 * The class that allows location to be serialized, and be used
 * in a file. This class should not be changed, otherwise it
 * will not work for older files.
 * 
 * @author Jnorr44
 */

public final class SerializableLocation implements Serializable {
    private static final long serialVersionUID = 8650311534439769069L;

    private final String world;
    private final String uuid;
    private final double x, y, z;
    private final float yaw, pitch;
    private transient Location loc;

    /**
     * Creates a new SerializableLocation instance of any org.bukkit.Location.
     * 
     * @param l
     */

    public SerializableLocation(Location l) {
        this.world = l.getWorld().getName();
        this.uuid = l.getWorld().getUID().toString();
        this.x = l.getX();
        this.y = l.getY();
        this.z = l.getZ();
        this.yaw = l.getYaw();
        this.pitch = l.getPitch();
    }

    /**
     * Gets the org.bukkit.Location back from any SerializableLocation.
     * 
     * @param l
     * @return
     */

    public static Location returnLocation(SerializableLocation l) {
        float pitch = l.pitch;
        float yaw = l.yaw;
        double x = l.x;
        double y = l.y;
        double z = l.z;
        World world = Bukkit.getWorld(l.world);
        Location location = new Location(world, x, y, z, yaw, pitch);
        return location;
    }

    // FROM HERE ON NEEDS DOC NOTES

    public SerializableLocation(Map<String, Object> map) {
        this.world = (String) map.get("world");
        this.uuid = (String) map.get("uuid");
        this.x = (Double) map.get("x");
        this.y = (Double) map.get("y");
        this.z = (Double) map.get("z");
        this.yaw = ((Float) map.get("yaw")).floatValue();
        this.pitch = ((Float) map.get("pitch")).floatValue();
    }

    public final Map<String, Object> serialize() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("world", this.world);
        map.put("uuid", this.uuid);
        map.put("x", this.x);
        map.put("y", this.y);
        map.put("z", this.z);
        map.put("yaw", this.yaw);
        map.put("pitch", this.pitch);
        return map;
    }

    public final Location getLocation(Server server) {
        if (loc == null) {
            World world = server.getWorld(this.uuid);
            if (world == null) {
                world = server.getWorld(this.world);
            }
            loc = new Location(world, x, y, z, yaw, pitch);
        }
        return loc;
    }
}

今、単に行う:

SerializableLocation loc = new SerializableLocation(LOCATION);

これが必要な理由は、、、 、、およびがLocation含まれているためです。worldxyzyawpitchworld

于 2012-09-03T02:42:48.860 に答える
-2

実際、あなたはシリアライズしようとしてPlayerLocationます、新しいクラスなどを実装しようとしています.しかし、なぜあなたはこれをしているのですか?

オブジェクトではなく、その文字列表現Playerを格納する方がよいでしょう。Locationたとえば、場所にPlayer.getName()and のようなものを使用できます"world:100:65:100"(したがって、によってすべてのデータを簡単にString.split(":")取得できます。これはより良いアプローチだと思います.

于 2013-04-02T02:29:56.100 に答える