繁体   English   中英

Java:在初始化块中初始化对象时,从另一个类调用对象的方法

[英]Java: Calling an object's method from another class when the object is initialized in the initialization block

我正在编写一个Percolation程序,该程序使用union-find对象中的方法,该对象属于不同的类。 渗透和联合发现的细节对于这个问题并不重要。

这就是我启动渗透类的方法,其中初始化了名为“uf”的“WeightedQuickUnionUF”对象。 方法“uf.union”在此块中使用没有问题:

public class Percolation{

private byte[][] grid;
private WeightedQuickUnionUF uf;
private int count;

public Percolation(int n){
    if (n<0) throw new IllegalArgumentException();
    grid = new byte[n][n];
    WeightedQuickUnionUF uf = new WeightedQuickUnionUF(n*n+2);

    // All Grid Points are closed (=0)
    for (int row=1; row<=n; row++){
        for (int col=1; col<=n; col++) grid[row-1][col-1]=0;    
    }

    // The Auiliary top and down squares
    int aux_u = 0;
    int aux_d = n*n+1;

    // Join the auiliary squares with top and bottom rows
    for (int col=1; col<=n; col++) uf.union(aux_u, getIndex(1, col));
    for (int col=1; col<=n; col++) uf.union(aux_d, getIndex(n, col));
} 

问题是当我想在Percolation类中的另一个方法中使用对象“uf”时。 例如,我创建了一个方法“Percolates”:

    public boolean percolates(){
    int n = grid[0].length;
    int aux_u = 0;
    int aux_d = n*n+1;
    return uf.connected(aux_u, aux_d);
    }

我没有得到任何编译错误,但无论何时在运行时调用此方法,我都会收到错误:

Exception in thread "main" java.lang.NullPointerException

其中,我认为这意味着“uf”在这一点上是一个空对象。 我的问题是,我是否需要在初始化块之外的其他地方初始化此对象? 为什么我对“网格”对象没有同样的问题? 那个也在初始化块初始化。

我相信上面的代码片段足以理解这个问题,但是我在这里发布了完整性的全部内容(代码可能不正确,我只是发布以给出上面特定问题的上下文)。 谢谢!

public class Percolation{

private byte[][] grid;
private WeightedQuickUnionUF uf;
private int count;

public Percolation(int n){
    if (n<0) throw new IllegalArgumentException();
    grid = new byte[n][n];
    WeightedQuickUnionUF uf = new WeightedQuickUnionUF(n*n+2);

    // All Grid Points are closed (=0)
    for (int row=1; row<=n; row++){
        for (int col=1; col<=n; col++) grid[row-1][col-1]=0;    
    }

    // The Auiliary top and down squares
    int aux_u = 0;
    int aux_d = n*n+1;

    // Join the auiliary squares with top and bottom rows
    for (int col=1; col<=n; col++) uf.union(aux_u, getIndex(1, col));
    for (int col=1; col<=n; col++) uf.union(aux_d, getIndex(n, col));
}

private int getIndex(int row, int col){
    int n = grid[0].length;
    if (row<1 || row>n) throw new IndexOutOfBoundsException("row " + row + "is not between 0 and " + n);
    if (col<1 || col>n) throw new IndexOutOfBoundsException("col " + col + "is not between 0 and " + n);
    int index = n*(row-1) + col;
    return index;
}   

public void open(int row, int col){
    int n = grid[0].length;
    if (row<1 || row>n) throw new IndexOutOfBoundsException("row " + row + "is not between 0 and " + n);
    if (col<1 || col>n) throw new IndexOutOfBoundsException("col " + col + "is not between 0 and " + n);

    if (grid[row-1][col-1] == 0){
        grid[row-1][col-1]=1; 
        count++;
    }

    if (col>1) connect(row, col, 'l');
    if (col<n) connect(row, col, 'r');
    if (row>1) connect(row, col, 'u');
    if (row<n) connect(row, col, 'd');
}

private void connect(int row, int col, char option){
    if (option=='l'){
        if (isOpen(row, col-1)) uf.union(getIndex(row,col), getIndex(row,col-1));
    }
    if (option=='r'){
        if (isOpen(row, col+1)) uf.union(getIndex(row,col), getIndex(row,col+1));
    }
    if (option=='u'){
        if (isOpen(row-1, col)) uf.union(getIndex(row,col), getIndex(row-1,col));
    }
    if (option=='d'){
        if (isOpen(row+1, col)) uf.union(getIndex(row,col), getIndex(row+1,col));
    }
}       

public boolean isOpen(int row, int col){
    int n = grid[0].length;
    if (row<1 || row>n) throw new IndexOutOfBoundsException("row " + row + "is not between 0 and " + n);
    if (col<1 || col>n) throw new IndexOutOfBoundsException("col " + col + "is not between 0 and " + n);
    if (grid[row-1][col-1] == 0) return false;
    else return true;
}

public boolean isFull(int row, int col){
    int n = grid[0].length;
    int aux_u = 0;
    if (row<1 || row>n) throw new IndexOutOfBoundsException("row " + row + "is not between 0 and " + n);
    if (col<1 || col>n) throw new IndexOutOfBoundsException("col " + col + "is not between 0 and " + n);
    return uf.connected(getIndex(row, col), aux_u);
}

public int numberOfOpenSites(){
    return count; 
}

public boolean percolates(){
    int n = grid[0].length;
    int aux_u = 0;
    int aux_d = n*n+1;
    return uf.connected(aux_u, aux_d);
}

public static void main(String[] args){
    Percolation Per = new Percolation(4);
    Per.open(3,2);
    StdOut.println("Percolates: " + Per.percolates());
}
}

private WeightedQuickUnionUF uf; 永远不会在代码中的任何位置初始化,因此它总是会导致空指针错误。

您可以通过简单地更改Percolation方法中的行来解决此问题,以便它设置类宽uf而不是创建一个无法在其他地方访问的新本地uf变量。

要做到这一点,只需更改此行:

WeightedQuickUnionUF uf = new WeightedQuickUnionUF(n*n+2);

看起来像这样:

uf = new WeightedQuickUnionUF(n*n+2);

我会尝试从私有类扩展您的公共类。 通过继承,您可以访问所有方法。 更好但是​​专门设置私有方法可访问我相信它的method.setAccessible()或类似的东西。 首先,你必须从你可以使用的实际类中获取方法.getDeclaredMethod(“method”); 它返回一个方法,因此你必须声明一个方法对象来接收它。 然后,您将该方法对象设置为可访问,您应该能够使用它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM