【JAVA】一种寻找错误的方法

相信在编写java的代码过程中,我们经常会碰到这样一个问题:明明代码的语法没有错误,运行过程中也没有报错,但为什么总是实现不了自己想要的功能呢?其实,这是常见的逻辑错误。我在初学的时候也是如此,但我慢慢学会使用“步骤跟踪法”即在恰当的位置使用打印输出语句来验证,就像《洋葱》这首歌里写的:“如果你愿意一层一层地剥开我的心。”这样就能找出错误,下面我就介绍给同样初学的大家。

下面来看两个例子:

public class drawPixelwyh {

public static void main(String[] args){

drawPixelwyh ui=new drawPixelwyh();

ui.showUI();

}

public void showUI(){

//其他代码省略...

//窗体:默认边框布局

JFrame jf=new JFrame();

Graphics g=jf.getGraphics();//画笔

jf.setVisible(true);

PixelMouse mouse=new PixelMouse();

mouse.gr=g;

}

}

public class PixelMouse implements MouseListener,ActionListener{

//全局变量:属性

public Graphics gr;  //保存传递过来的画笔对象

gr.drawImage(bufferImage, 40, 90,1080,540, null);

这个错误是非常常见的空指针错误。我们先按下解决方法不谈,先按照一步步来检验错误(运行时错误出现在代码最后一行)。

bufferImage这里不可能错误,因为就算这里是空对象系统也是不会报错的,而只有在调用空对象(gr)的方法时才会出错。

②因此,我们在报错的前一行使用打印语句: System.out.println("gr:"+gr);这时会输出:gr:null这样就验证了我们的想法是正确的。

然后我们再在mouse.gr=g;前写一行打印语句System.out.println("传入前的g:"+g);这时会输出传入前的g:null。这样就说明了我们在传入前的画笔g就已经是空对象了。

④然后我们再检查这一行前面的代码,发现是Graphics g=jf.getGraphics();jf.setVisible(true);这两行的位置弄反了,因为获取画笔必须在窗体可见之后,这时我们就知道如何修改了。

或许这个错误比较显而易见,但对初学者的我们来说这种解决问题的思路是非常重要的,这样不仅可以解决问题,更重要的是能再一次理清自己编写代码时的逻辑。

再来看一个例子:

public class Threadop extends Thread{

public Graphics gr;

public int op;

public BufferedImage bufferImage;

public Pixel pixel = new Pixel();

public String name; //区分不同处理效果

public Threadop(Graphics g){

this.gr=g;

System.out.println("创建线程对象");

}

public void setop(int op){

this.op=op;

}

public void setPixelName(String n) {

name = n;

}

public void run(){

Webcam webcam = Webcam.getDefault();

    webcam.open();

while(true){

     bufferImage=webcam.getImage();

     //System.out.println("进入while循环:"+name);

     System.out.println("gr="+gr);

     gr.drawImage(bufferImage, 300, 150, 540, 540, null);

}

}

}

public class PixelMouse implements MouseListener,ActionListener{

public Threadop tr=new Threadop(gr);

public void actionPerformed(ActionEvent e){

     name = e.getActionCommand();

     if("打开摄像头".equals(name)){

     tr.start();

     System.out.println(tr+"  op  "+tr.op);

     }

}

}

public class drawPixelwyh {

public static void main(String[] args){

drawPixelwyh ui=new drawPixelwyh();

ui.showUI();

}

public void showUI(){

//其他代码省略...

//窗体:默认边框布局

JFrame jf=new JFrame();

jf.setVisible(true);

Graphics g=jf.getGraphics();//画笔

PixelMouse mouse=new PixelMouse();

System.out.println("开始传画笔");

mouse.gr=g;

}

}

在这里同样会报空指针错误(nullpointerexception),同时错误出现在“gr.drawImage(bufferImage, 300, 150, 540, 540, null);这一行。我们从上个例子类似可知,只有调用空对象的方法系统才会报错,但我们明明在创建线程类的构造方法中把PixelMouse中的画笔传过去了,而PixelMouse中的gr也已经在drawPixel的showUI()方法中的mouse.gr=g;语句中绑定在窗体的画笔上了,这是怎么回事呢?想要解决这个问题,同样需要用到步骤跟踪法,下面是具体步骤:

①我们在线程类中的run方法出错前一行打印画笔:System.out.println("gr="+gr);这时输出gr=null;符合我们的猜想。

②我们在线程类的构造方法中打印输出语句:System.out.println("创建线程对象");同时在showUI方法的

mouse.gr=g;前使用打印语句System.out.println("开始传画笔");这时输出结果:创建线程对象 开始传画笔。因此我们要注意这个问题:类在运行过程中,首先是实现其具有的属性(PixelMouse中的tr这个线程对象),再实现其拥有的方法(drawPixel中的mouse.gr=g这个方法不同于一般明显写出的方法),所以我们在构造方法中想将画笔传过去是不可行的,因为此时窗体上的画笔还没有获取,自然tr中的画笔就是空的了。

③因此我们可以这样改正:写构造方法时并不需要传画笔,而是在PixelMouse中的actionPerformed方法里加tr.gr=gr;语句来传画笔 ,这样就可以避免这个问题,同时也不要忘记创建线程对象tr时不需要参数gr。

总结:

通过这两个例子,我们初学者不仅可以学会如何自己寻找错误,也可以理清自己编写程序时的逻辑,希望这个方法能给大家一些帮助!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值