从java类调用kotlin void时出现问题



我试图制作kotlin库,但当我测试它时(我用java做的,很抱歉-我是kotlin的新手(,它抛出了错误。问题出在哪里?

原始代码,我正在从中制作kotlin库:

package me.engo.originalproject;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Objects;
import java.util.Random;
public class Main
{
private boolean button = true;
private Clip clip = null;
private int i = 0;
private JPanel panel;
private JLabel label;
private static JFrame frame;
public Main()
{
label.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
if (e.getButton() == 1 && button)
{
new Thread(() -> {
label.setIcon(new ImageIcon(Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("dead.png"))));
frame.setTitle(String.valueOf(Integer.parseInt(frame.getTitle()) + 1));
button = false;
new Thread(() -> {
try
{
if (clip != null) clip.stop();
int random = new Random().nextInt(4) + 1;
if (i != 0)
{
while (i == random)
{
random = new Random().nextInt(4) + 1;
}
}
i = random;
AudioInputStream audioIn = AudioSystem.getAudioInputStream(Thread.currentThread().getContextClassLoader().getResource("0" + random + ".wav"));
clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
} catch (Exception exc)
{
exc.printStackTrace();
}
}).start();
try
{
Thread.sleep(100);
} catch (Exception ex)
{
ex.printStackTrace();
}
label.setIcon(new ImageIcon(Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("alive.png"))));
button = true;
}).start();
}
}
});
}
public static void main(String[] args)
{
frame = new JFrame("0");
frame.setContentPane(new Main().panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
frame.setResizable(false);
}
}

科特林图书馆类:

package me.engo.library
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import java.util.*
import javax.sound.sampled.AudioSystem
import javax.sound.sampled.Clip
import javax.swing.ImageIcon
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.JPanel

class Template(val sounds: Int, private val panel: JPanel, val label: JLabel)
{
var button: Boolean = true
lateinit var frame: JFrame
lateinit var clip: Clip
var i: Int = 0
fun doListener()
{
println("A")
label.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
println("B")
if (e.button == 1 && button) {
println("C")
Thread {
label.icon = ImageIcon(
Objects.requireNonNull(
Thread.currentThread().contextClassLoader.getResource("dead.png")
)
)
frame.title = (frame.title.toInt() + 1).toString()
button = false
if (sounds != 0)
{
Thread {
try {
if (clip != null) clip.stop()
var random: Int = Random().nextInt(sounds - 1) + 1
if (i != 0) {
while (i == random) {
random = Random().nextInt(sounds - 1) + 1
}
}
i = random
val audioIn = AudioSystem.getAudioInputStream(
Thread.currentThread().contextClassLoader.getResource("0$random.wav")
)
clip = AudioSystem.getClip()
clip.open(audioIn)
clip.start()
} catch (exc: Exception) {
exc.printStackTrace()
}
}.start()
}
try {
Thread.sleep(100)
} catch (ex: Exception) {
ex.printStackTrace()
}
label.icon = ImageIcon(
Objects.requireNonNull(
Thread.currentThread().contextClassLoader.getResource("alive.png")
)
)
button = true
}.start()
}
}
})
}
fun doMain()
{
label.icon = ImageIcon(
Objects.requireNonNull(
Thread.currentThread().contextClassLoader.getResource("alive.png")
)
)
frame = JFrame("0")
frame.contentPane = panel
frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
frame.pack()
frame.isVisible = true
frame.isResizable = false
}
}

java测试无效:

package me.engo.library;
import javax.swing.*;
public class Test
{
private JPanel panel;
private JLabel label;
static Template template = new Template(5, new Test().panel, new Test().label);
public static void main(String[] args)
{
template.doMain();
}
public Test()
{
template.doListener();
}
}

IDK,这里怎么了。。。

顺便说一句,异常:

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at me.engo.killtemplate.Test.<init>(Test.java:19)
at me.engo.killtemplate.Test.<clinit>(Test.java:10)

很抱歉,如果这很明显的话,但我什么也没看到。谢谢你的帮助。

您可以从Test类中看到问题。考虑JVM加载类时会发生什么:

  • 在获得代码&c、 它运行任何静态初始化程序。这个类有一个:static Template template字段。因此,它评估初始化程序表达式:

    • 为了评估初始化程序表达式,它构造了Template的实例。这调用Template构造函数:

      • 构造函数调用template上的一个方法。但是,template尚未设置

template在JVM知道将其设置为之前无法设置,并且在构建实例之前无法设置。

因此(因为Java中的所有字段一开始都设置为null/0/false(template实际上在这一点上保持null。因此,NullPointerException在尝试调用其上的方法时。

实际上,您有一个死锁:在创建实例之前,无法设置模板字段;但是,在设置了template字段之后,才能创建实例。

要解决这个问题,您需要以某种方式打破僵局。(也许最简单的方法是在尝试在构造函数中使用模板之前检查模板是否为null。(

相关内容

最新更新