Kotlin不能在init中使用“this”

我想把game设置为一个新的Game实例,我想把它传递给游戏。 所以我就是这样

 var game: Game init { game = Game(this) } 

我也试过了

 var game: Game = Game(this) 

在运行时都抛出了一个NullPointer ,但在Intellij中看起来没问题,编译也没有问题。 我究竟做错了什么?

堆栈跟踪

 org.bukkit.plugin.InvalidPluginException: java.lang.NullPointerException at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:135) ~[server.jar:git-Spigot-21fe707-e1ebe52] at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:329) ~[server.jar:git-Spigot-21fe707-e1ebe52] at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:251) [server.jar:git-Spigot-21fe707-e1ebe52] at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugins(CraftServer.java:292) [server.jar:git-Spigot-21fe707-e1ebe52] at net.minecraft.server.v1_8_R3.DedicatedServer.init(DedicatedServer.java:198) [server.jar:git-Spigot-21fe707-e1ebe52] at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:525) [server.jar:git-Spigot-21fe707-e1ebe52] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121] Caused by: java.lang.NullPointerException at org.bukkit.plugin.SimplePluginManager.registerEvents(SimplePluginManager.java:523) ~[server.jar:git-Spigot-21fe707-e1ebe52] at me.darkpaladin.uhc.game.gameSettings.GameSettingsManager.addGameSettings(GameSettingsManager.kt:43) ~[?:?] at me.darkpaladin.uhc.game.gameSettings.GameSettingsManager.<init>(GameSettingsManager.kt:20) ~[?:?] at me.darkpaladin.uhc.game.Game.<init>(Game.kt:49) ~[?:?] at me.darkpaladin.uhc.UHC.<init>(UHC.kt:20) ~[?:?] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_121] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_121] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_121] at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_121] at java.lang.Class.newInstance(Class.java:442) ~[?:1.8.0_121] at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:76) ~[server.jar:git-Spigot-21fe707-e1ebe52] at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:131) ~[server.jar:git-Spigot-21fe707-e1ebe52] ... 6 more 

UHC类

 var game: Game init { game = Game(this) } override fun onReady() { // new Lobby(Bukkit.getWorld("world"), this, false); TeamManager() registerCommands() } fun registerCommands() { val c = commandHandler c.addCommand( TeamCommand(), SetGameTypeCommand(game), ClaimHostCommand(game), StartGameCommand(game), ScenarioManagerCommand(game), KillTopCommand(game), ConfigCommand(game), ScatterCommand(game) ) } fun registerListeners() { val p = Bukkit.getPluginManager() p.registerEvents(GamePlayerListener(game), this) } 

游戏类

 package me.darkpaladin.uhc.game import me.darkpaladin.core.Core import me.darkpaladin.core.utils.CoreUtils import me.darkpaladin.core.utils.PacketUtils import me.darkpaladin.uhc.UHC import me.darkpaladin.uhc.events.GameStartEvent import me.darkpaladin.uhc.events.GameStopEvent import me.darkpaladin.uhc.game.gameEvents.GameEvent import me.darkpaladin.uhc.game.gameEvents.GameEventRunnable import me.darkpaladin.uhc.game.gamePlayers.GamePlayer import me.darkpaladin.uhc.game.gamePlayers.GamePlayerManager import me.darkpaladin.uhc.game.gameSettings.GameSettingsManager import me.darkpaladin.uhc.scenarios.ScenarioManager import org.apache.commons.lang.WordUtils import org.bukkit.* import org.bukkit.entity.Item import org.bukkit.entity.Monster import org.bukkit.entity.Player import org.bukkit.scheduler.BukkitRunnable import java.util.* /** * Created by Caleb on 4/28/2017. */ class Game(private val plugin: UHC) { var gameType = GameType.NORMAL var gameState = GameState.SETTING_UP var gameStartTicks = (CoreUtils.ticksPerSecond * 10).toLong() var finalHealTime = (CoreUtils.ticksPerSecond * 15).toLong() var pvpTicks = (CoreUtils.ticksPerSecond * 20).toLong() var meetupTicks = (CoreUtils.ticksPerSecond * 25).toLong() var isBorderShrink = true var episodeLength = (CoreUtils.ticksPerMinute * 20).toLong() private var episode = 1 private val worlds = ArrayList<World>() private val gameEvents = ArrayList<GameEvent>() var gameTicks: Long = 0L var hostUuid: UUID? = null val scenarioManager: ScenarioManager = ScenarioManager(this) val gamePlayerManager: GamePlayerManager = GamePlayerManager() val gameSettingsManager: GameSettingsManager = GameSettingsManager(this) private val instance: Game init { worlds.add(Bukkit.getWorld("world")) //TODO: remove instance = this } val overworld: World? get() = getWorldWithEnvironment(World.Environment.NORMAL) val nether: World? get() = getWorldWithEnvironment(World.Environment.NETHER) val end: World? get() = getWorldWithEnvironment(World.Environment.THE_END) fun getWorldWithEnvironment(environment: World.Environment): World? { return worlds.firstOrNull { it.environment == environment } } fun addGameEvent(vararg events: GameEvent) { gameEvents.addAll(Arrays.asList(*events)) } val host: Player get() = Bukkit.getPlayer(hostUuid) fun start() { gameState = GameState.STARTING val finalHeal = GameEvent("Final Heal", finalHealTime, object : GameEventRunnable(this) { override fun run() { Bukkit.getOnlinePlayers().forEach { player -> player.health = player.maxHealth } CoreUtils.broadcast(Core.PREFIX + "Final Heal has been given. This is the FINAL heal. Do not ask for more.") } }) val pvp = GameEvent("PvP", pvpTicks, object : GameEventRunnable(this) { override fun run() { for (world in worlds) { world.pvp = true world.setGameRuleValue("doMobSpawning", "true") } } }) val starting = GameEvent("Starting in", gameStartTicks, object : GameEventRunnable(this) { override fun run() { gameTicks = 0L addGameEvent(finalHeal, pvp) if (isBorderShrink) addGameEvent(BorderShrinkGameEvent(meetupTicks, instance)) for (player in Bukkit.getOnlinePlayers()) { player.health = player.maxHealth player.foodLevel = 20 player.saturation = 20f player.level = 0 player.exp = 0f player.totalExperience = 0 player.closeInventory() player.inventory.clear() player.inventory.armorContents = null player.gameMode = GameMode.SURVIVAL player.activePotionEffects.forEach { potionEffect -> player.removePotionEffect(potionEffect.type) } } for (world in worlds) { for (entity in world.entities) { if (entity is Item || entity is Monster) { entity.remove() } } world.pvp = false world.difficulty = Difficulty.HARD world.time = 20 world.setSpawnFlags(false, false) } Bukkit.getOnlinePlayers().forEach { player -> gamePlayerManager.addGamePlayers(GamePlayer(player.uniqueId)) } val players = ArrayList<Player>() gamePlayerManager.aliveGamePlayers .filter { gamePlayer -> gamePlayer.player != null } .forEach { gamePlayer -> players.add(gamePlayer.player) } scenarioManager.giveStartingItems(players) gameState = GameState.RUNNING Bukkit.getPluginManager().callEvent(GameStartEvent(instance)) } }) addGameEvent(starting) GameTimer().runTaskTimer(plugin, 0, 1) if (gameType === GameType.RECORDED) EpisodeTimerTask() } val nextEvent: GameEvent? get() { val events = gameEvents val times = HashMap<GameEvent, Long>() events.forEach { gameEvent -> times.put(gameEvent, gameEvent.time) } var nextEvent: GameEvent? = null var nextEventTime: Long = 999999999999999999L for (event in times.keys) { if (event.time < nextEventTime) { nextEvent = event nextEventTime = event.time } } return nextEvent } fun getNextBorderRadius(world: World): Int { return Math.round(world.worldBorder.size / 2 * .75).toInt() } private inner class GameTimer : BukkitRunnable() { override fun run() { val nextEvent = nextEvent if (nextEvent != null) { if (gameTicks!! % 20 == 0L) { PacketUtils.sendAction(Core.HIGHLIGHTED_COLOR.toString() + ChatColor.BOLD.toString() + WordUtils.capitalizeFully(nextEvent.name) + Core.EXTRA_COLOR + " » " + Core.HIGHLIGHTED_COLOR + CoreUtils.formatTicks(nextEvent.time - gameTicks!!)) } if (gameTicks >= nextEvent.time) { nextEvent.runnable!!.run() gameEvents.remove(nextEvent) } } gameTicks++ } } private inner class BorderShrinkGameEvent(time: Long, game: Game) : GameEvent("Border Shrink", time, object : GameEventRunnable(game) { override fun run() { for (world in worlds) { val wb = world.worldBorder val radius = Math.round(wb.size / 2).toInt() val newRadius = Math.round(wb.size / 2 * .75).toInt() if (newRadius < 50) wb.size = 100.0 else wb.size = (newRadius * 2).toDouble() CoreUtils.broadcast(Core.PREFIX + "The border has shrunk from " + radius + " to " + Math.round(wb.size / 2).toInt() + "!") if (wb.size > 100) { game.addGameEvent(BorderShrinkGameEvent(CoreUtils.ticksPerSecond * 5 + game.gameTicks!!, game)) } } } }) private inner class EpisodeTimerTask : BukkitRunnable() { private var ticks: Long = 0 init { ticks = episodeLength } override fun run() { if (ticks <= 0) { cancel() CoreUtils.broadcast(Core.PREFIX + "End of episode " + episode + ". Start episode " + episode + 1) episode++ return } ticks-- } } fun stop() { scenarioManager.disableAll() Bukkit.getPluginManager().callEvent(GameStopEvent(this)) plugin.game = Game(plugin) } } 

游戏设置管理器

 package me.darkpaladin.uhc.game.gameSettings import me.darkpaladin.core.Core import me.darkpaladin.uhc.game.Game import org.bukkit.Bukkit import org.bukkit.event.Listener import java.util.ArrayList import java.util.Arrays import java.util.stream.Collectors /** * Created by caleb on 5/6/17. */ class GameSettingsManager(game: Game) { private val gameSettings = ArrayList<GameSetting>() init { addGameSettings( FriendlyFireGameSetting(game), NotchApplesGameSetting(), DoubleArrowsGameSetting() ) } fun getGameSettings(): List<GameSetting> { return gameSettings } val toggleableGameSettings: List<ToggleableGameSetting> get() { val settings = ArrayList<ToggleableGameSetting>() for (setting in getGameSettings()) if (setting is ToggleableGameSetting) settings.add(setting) return settings } fun addGameSettings(vararg gameSettings: GameSetting) { this.gameSettings.addAll(Arrays.asList(*gameSettings)) for(setting in gameSettings) Bukkit.getPluginManager().registerEvents(setting as Listener, Core.instance) } fun getGameSetting(name: String): GameSetting { return gameSettings.stream() .filter { gameSetting -> gameSetting.name.equals(name, ignoreCase = true) } .collect(Collectors.toList<GameSetting>())[0] } } 

GameSettingsManager第43行:

 fun addGameSettings(vararg gameSettings: GameSetting) { this.gameSettings.addAll(Arrays.asList(*gameSettings)) for(setting in gameSettings) //line 43 is the one below this Bukkit.getPluginManager().registerEvents(setting as Listener, Core.instance) } 

被传递到Bukkit.getPluginManager()一个setting对象为null

或者Core.Instancenull

另一种可能性是由getPluginManager()返回的对象在其中有一个单位变量,它在registerEvents()函数中被引用。

但最有可能的情况是你的一个setting对象是null或者Core.Instance是null。

编辑

https://github.com/Bukkit/Bukkit/blob/master/src/main/java/org/bukkit/plugin/SimplePluginManager.java

以下是运行的bukkit库中SimplePluginManagerregisterEvents()函数:

 public void registerEvents(Listener listener, Plugin plugin) { if (!plugin.isEnabled()) { //the next line is 523 throw new IllegalPluginAccessException("Plugin attempted to register " + listener + " while not enabled"); } for (Map.Entry<Class<? extends Event>, Set<RegisteredListener>> entry : plugin.getPluginLoader().createRegisteredListeners(listener, plugin).entrySet()) { getEventListeners(getRegistrationClass(entry.getKey())).registerAll(entry.getValue()); } } 

根据你的堆栈跟踪线523是抛出null指针异常的那个。 所以有些东西是null 。 listener变量来自你的gameSettings数组。

看看你的代码真的不应该在该gameSettings varargs数组中的null 。 但是抛出错误的功能就是说。 这将是一个好主意,调试到该位置或做一个println作为您的循环通过gameSettings数组来验证没有一个是null。