我一直在试图弄清楚如何从classA中为classA创建一个List 我已经尝试创建列表的实例/对象,但是当我得到列表的大小时它总是返回空(在主类中它不是空的)。
示例:
ClassA的:
List<String> players = new ArrayList<String>();
如果我在这里使用players.size()
,它将返回2例如
ClassA classA = new ClassA();
List<String> newList = classA.players;
无论如何, newList.size()
总是会返回0。
我也尝试过使用吸气剂,但这似乎没什么区别。
示例:
ClassA的:
List<String> players = new ArrayList<String>();
public List<String> getList(){
return this.players;
}
ClassB:
ClassA.getList().size()
这也将始终返回0
我该如何正确地做到这一点?我尝试使用静态,似乎工作,但我被告知:
他告诉我:“静态不是工作的正确工具。它是一种内存管理 工具,而不是访问修饰符。“
您可以传递而不是静态而不是创建新实例 实例到其他类,通过将它们作为参数添加到 构造
然而,我并没有真正理解他的意思。如果有人能用一个令人惊奇的例子解释这一点。提前谢谢!
修改:由于很多人都没有达到我想要的地方,我会发布我的来源: 在示例中称为ClassA
public class TeamManager {
String prefix = new Messages().prefix;
List<String> players = new ArrayList<String>();
List<String> human = new ArrayList<String>();
List<String> infected = new ArrayList<String>();
void join(Player p){
if(!players.contains(p.getName())){
players.add(p.getName());
teleportToLobby(p);
for (String temp : players) {
Bukkit.getPlayer(temp).sendMessage("§e§l"+p.getName()+ " has joined infection. §7("+players.size()+"/16)");
}
}else{
p.sendMessage(prefix + "§cFailed. You are already in the game!");
}
}
void leave(Player p){
if(players.contains(p.getName())){
p.teleport(Bukkit.getWorlds().get(0).getSpawnLocation());
players.remove(p.getName());
for (String temp : players) {
Bukkit.getPlayer(temp).sendMessage("§7§l"+p.getName()+ " has left infection. §7("+players.size()+"/16)");
}
}else{
p.sendMessage(prefix + "§cYou are not in a game!");
}
}
void addToHumans(String playername){
human.add(playername);
}
void removeFromHumans(String playername){
human.remove(playername);
}
void addToInfected(String playername){
infected.add(playername);
}
void removeFromInfected(String playername){
infected.remove(playername);
}
void teleportToLobby(Player p){
Location lobby = getLocFromConfig("lobby");
if(lobby != null){
p.teleport(lobby);
p.sendMessage(prefix + "§aSuccessfully added to game!");
}else{
p.sendMessage(prefix + "§cLobby not set! Make sure to set a lobby using /infection setlobby");
}
}
void startGame(){
/*if(human.size() >= 4){
}*/
for (String temp : players) {
Bukkit.getPlayer(temp).sendMessage("Game will start shortly!");
}
}
Location getLocFromConfig(String locationName){
if(Main.plugin.getConfig().get("lobby") != null){
double x = Main.plugin.getConfig().getInt(locationName+".x");
double y = Main.plugin.getConfig().getInt(locationName+".y");
double z = Main.plugin.getConfig().getInt(locationName+".z");
World world = Main.plugin.getServer().getWorld(Main.plugin.getConfig().getString(locationName+".world"));
Location l = new Location(world, x, y, z);
return l;
}else{
Bukkit.getLogger().warning("[Infection] Lobby has not been set!");
return null;
}
}
int getPlayersInLobby(){
return players.size();
}
public List<String> getPlayers(){
List<String> players = this.players;
return players;
}
public List<String> getHumans(){
return human;
}
public List<String> getInfected(){
return infected;
}
}
事件类(在示例中称为ClassB)
public class Events implements Listener{
TeamManager teamman = new TeamManager();
List<String> players = teamman.getPlayers();
List<String> humans = teamman.getHumans();
List<String> infected = teamman.getInfected();
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e){
//Player p = (Player) e.getPlayer();
//e.setJoinMessage("["+lvl+"]" + e.getPlayer().getName() +"has joined the game!");
//p.setDisplayName("[lvl1]"+p.getName());
}
@EventHandler
public void onPlayerDamage(EntityDamageByEntityEvent e){
if(e.getEntity() instanceof Player){
Player p = (Player) e.getEntity();
Bukkit.getServer().broadcastMessage("Players: "+ players);
if(players.contains(p.getName())){
if((p.getHealth() - p.getLastDamage()) < 1){
for (String temp : players) {
Bukkit.getPlayer(temp).sendMessage("§c"+p.getName()+" got infected by "+p.getKiller().getName()+"!");
}
e.setCancelled(true);
p.setHealth(20);
teamman.addToInfected(p.getName());
teamman.removeFromHumans(p.getName());
p.sendMessage("§cYou have been infected!!");
}
}
}
}
}
如上所述,我希望能够从TeamManager访问列表并在事件中使用它们。正如解释players
在Events类中是空的。我希望这会有所帮助。
答案 0 :(得分:0)
每次你做
ClassA classA = new ClassA();
List<String> newList = classA.players;
将创建/拥有在ClassA中声明的ArrayList的新实例。
并且,因为下面的代码行是一个实例变量。因此,每个实例都有不同的副本。
List<String> players = new ArrayList<String>();
所以,解决方案是:
ClassA classA = new ClassA();
classA.players.add("A");
List<String> newList = classA.players;
或者在构造函数中使用setter方法或初始化,或者将其声明为静态成员。这一切都将取决于您的要求。
您可以传递而不是静态而不是创建新实例 实例到其他类,通过将它们作为参数添加到 构造
这意味着您可以使用构造函数将ClassA实例传递给ClassB。
答案 1 :(得分:0)
我认为你的问题是你没有独立思考这些对象。只有在B类中初始化A类实例时,才能对该实例进行变异。
然后你可以将对象从B类传递到你想要的地方,但你不能从类a初始化类A然后直接在类B中使用它,除非你将它传递给B类
答案 2 :(得分:0)
A的列表将始终为空,因为您正在访问新实例的列表。如果要获取列表A,则已将列表A作为参数发送到B类。示例:
class ClassA{
List<String> players;
ClassA(){
players = new ArrayList<>();
}
public List getPlayers(){
return this.players;
}
}
class ClassB{
private List<String> playersA;
ClassB(List playersA){
this.playersA = playersA;
}
}
// In your main code
ClassA classA = new ClassA();
ClassB classB;
List<String> players = classA.getPlayers();
players.add("P1");
players.add("P2");
classB = new ClassB(players);
答案 3 :(得分:0)
简单的答案是您需要将您创建的ClassA实例传递给ClassB。
创建类时,将创建类定义。每次使用new
关键字时,都会创建该类的新实例。假设您有足够的内存,您可以拥有任意数量的类实例。但每个实例都与其他实例分开。
就像String和List是类并且需要实例化一样,您的自定义类也可以。因此,在您的主要内容或您使用ClassA和ClassB的任何地方,您都希望将它们实例化为:
ClassA instanceOfClassA = new ClassA();
ClassB instanceOfClassB = new ClassB();
我们假设,因为你没有指明,你是在主要的那样做的。
您的目标:从ClassB中访问ClassA的特定实例列表。
您已经在ClassA中创建了getList()方法。这很好。你会使用它。
接下来,您将要在ClassB中创建类型为ClassA的数据成员,以及该成员的getter和setter:
public class ClassB {
...
ClassA myInstanceOfClassA;
public void setClassAInstance(ClassA instance){
this.myInstanceOfClassA = instance;
}
public ClassA getClassAInstance(){
return this.myInstanceOfClassA;
}
}
然后,在您更新了ClassA实例中的players
之后,以及在您实例化了上面的ClassB实例之后,返回主页:
instanceOfClassB.setClassAInstance(instanceofClassA);
然后在ClassB中,可以使用该实例访问players
的列表。
List<String> playersFromClassA = myInstanceOfClassA.getList();
同样,从ClassB内部调用myInstanceOfClassA.getList().size();
应返回适当数量的玩家。