You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Processing静态类中实例化Datum对象且不创建主类实例?

Processing 4静态工具类调用内部类的问题解决

问题背景

我正在用Java编写Processing 4程序,主类GeometryView继承自PApplet,代码如下:

ArrayList<Datum> datums = new ArrayList<Datum>();

void setup(){
  size(1400, 900);
  surface.setResizable(true);
  //fullScreen();
  frameRate(120);
  datums.add(new Datum(0,0));
  datums.add(new Datum(1,2));
  datums.add(new Datum(3,4));
}

void draw() {
  background(30);
  stroke(220);
  if(Functions.convex(datums.get(0),datums.get(1),datums.get(2))){
    println("These points are part of a convex corner of geometry");
  }
}

用于存储坐标的Datum类在单独标签页:

class Datum {
  float x;
  float y;
  
  Datum(float x, float y){
    this.x = x;
    this.y = y;
  }

  void drawDatum(int size){
    //print("X = " + this.x + ", Y = " + this.y);
    ellipse(this.x, -this.y, size, size);
  }
  
  Datum clone(){
    return new Datum(x,y);
  }
}

静态工具类Functions中调用new Datum(x,y)时出现错误:

No enclosing instance of type GeometryView is accessible. Must qualify the allocation with an enclosing instance of type GeometryView.

若将Datum设为静态,drawDatum方法调用ellipse时又报错:

Cannot make a static reference to the non-static method ellipse(float, float, float, float) from the type PApplet

不想通过实例化整个主类解决问题,询问如何在Functions中使用new Datum(x,y)且不破坏现有程序,以及创建主类引用是否会引发内存问题。

错误原因分析

  1. 第一个错误:Datum是非静态内部类,默认持有外部类GeometryView的引用,静态类Functions没有外部类实例,无法直接创建非静态内部类的对象。
  2. 第二个错误:ellipse是PApplet的非静态方法,静态类Datum无法直接调用非静态成员,必须通过PApplet实例访问。

解决方案

方案1:将Datum改为静态内部类,并修改drawDatum方法

把Datum声明为静态内部类,同时让drawDatum接收PApplet实例作为参数,通过该实例调用ellipse:

static class Datum {
  float x;
  float y;
  
  Datum(float x, float y){
    this.x = x;
    this.y = y;
  }

  void drawDatum(PApplet app, int size){
    app.ellipse(this.x, -this.y, size, size);
  }
  
  Datum clone(){
    return new Datum(x,y);
  }
}

在主类中调用drawDatum时传入this(主类本身就是PApplet实例):

datums.get(0).drawDatum(this, 10);

这样Functions类中可以直接new Datum(x,y),因为静态内部类不需要外部类实例。

方案2:将Datum改为顶级类

把Datum移到单独的.java文件中(成为顶级类),这样它不属于任何内部类,静态类Functions可以直接创建Datum对象。同时修改drawDatum方法,同样接收PApplet实例:

// Datum.java文件
public class Datum {
  float x;
  float y;
  
  public Datum(float x, float y){
    this.x = x;
    this.y = y;
  }

  public void drawDatum(PApplet app, int size){
    app.ellipse(this.x, -this.y, size, size);
  }
  
  public Datum clone(){
    return new Datum(x,y);
  }
}

主类调用方式和方案1一致,这种方式结构更清晰,适合工具类的复用。

关于主类引用的内存疑问

如果只是在Functions中持有主类GeometryView的引用,不会引发内存问题——因为主类本身就是程序运行的核心实例,只要没有循环引用(比如GeometryView又持有Functions的静态引用且无法释放),就不会有内存泄漏。但相比之下,上面的两种方案不需要额外持有主类引用,代码更简洁优雅,更推荐使用。

内容的提问来源于stack exchange,提问作者Andrew Cline

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:01:07