静态类更新静态变量,但静态方法不更新静态变量

时间:2011-04-29 00:11:05

标签: java static-methods

我搜索了几页,但大多数似乎只是对静态意味着什么的理解问题。我遇到的问题在于我们使用的是静态类,FocusListener和ActionListener。具有事件处理的类调用静态类,并且当填充JTextfield并从FocusListener选中时,立即更新该静态变量。当所有JTextfields都被填充并且FocusListener更新了变量时,就会有一个提交JButton。单击该按钮后,将调用静态方法以完成使用先前更新的变量计算的任何变量。用户不知道这一点。变量虽然没有更新,但我很好奇我是否实现了这个错误?提前谢谢。

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class WellParameters extends JInternalFrame implements FocusListener, ActionListener {
    JLabel  measuredDepthL, ..., pitGainL, drillBitSizeL, 
                mudInActivePitsL, mainPanelLabel;
        JTextField  measuredDepthT, ..., pitGainT, drillBitSizeT, mudInActivePitsT;
        JPanel  mainPanel, firstPanel, secondPanel, thirdPanel, fourthPanel, submitButtonPanel;
        JButton submitButton;

        WellParameters() {  
            super("Well Parameters", true, true, false, true);
            this.setBounds(0, 0, 600, 385);
            this.setVisible(true);
            this.setLayout(new BorderLayout());

            ...//GUI Stuff

            this.add(submitButtonPanel, BorderLayout.SOUTH);
        }
    @Override
    public void focusGained(FocusEvent e) {} //Ignore this!

    @Override
    public void focusLost(FocusEvent e) {
        try {
            if(e.getSource() == measuredDepthT) {
                KillWellCalculations.measuredDepth = Integer.parseInt(measuredDepthT.getText());

              ...//Others 

            } else if(e.getSource() == mudInActivePitsT) {
                KillWellCalculations.mudInActivePits = Double.parseDouble(mudInActivePitsT.getText());
            }
        } catch (Exception ignore) {}

    }
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            if(e.getSource() == submitButton) {
            System.out.println(KillWellCalculations.pumpEfficiency);
            KillWellCalculations.setPressureBeforeCasingBurstAndFormationFracture(); //Doesn't work
            KillWellCalculations.setCirculatingPressures();
            KillWellCalculations.setTriplexPumpCapacity();
            System.out.println(KillWellCalculations.mudInActivePits);
            System.out.println(KillWellCalculations.pumpFactor);
            System.out.println(KillWellCalculations.finalCirculatingPressure);}
        }
        catch(Exception ignore) {}
    }
}

那是GUI,这是静态类......它们是2个独立的类。不在同一个文件中。 包killwellsheet;

public class KillWellCalculations {

    static int measuredDepth;           //Total Depth from open hole to bottom

        ... //Tons of other variables

    static double totalStrokes;         //add strokes

    //Used to set different circulating pressures for the well
    public static void setCirculatingPressures() {
        initialCirculatingPressure = circulatingPressureKillRate + shutInDrillPipePressure;
        finalCirculatingPressure = circulatingPressureKillRate * (killMudWeight/currentMudWeight);
    }   
    //Calculates capacity of anypipe
    private static double pipeCapacity(double length, double insideDiameter) {
        return length * ((insideDiameter*insideDiameter)/1029.4);
    }
    //Calculates capacity of the annulus/open hole
    private static double annulusCapacity(double length, double insideDiameter, double outsideDiameter) {
        return length * (((insideDiameter*insideDiameter)-(outsideDiameter*outsideDiameter))/1029.4);
    } 

         ... //Other functions

    //Set the casing burst pressure
    public static void setPressureBeforeCasingBurstAndFormationFracture() {
        beforeCasingBurst = burstPressure*0.70;
        beforeFormationFracture = (0.052*casingShoeDepth)*(fracGradientMWEquivalent - currentMudWeight);
    }
    public static void bariteNeedAndVolumeIncrease() {
        bariteSacksRequired = (totalMudVolume/100)*((1099*(killMudWeight-currentMudWeight))/(28.35-killMudWeight));
        increaseInMudVolume = 0.091*bariteSacksRequired;
    }
    public static void pumpStrokes() {
        surfaceToBit = (mudInDrillString)/pumpFactor;
        bitToSurface = (mudInAnnulus)/pumpFactor;
        totalStrokes = surfaceToBit + bitToSurface;
    }
}//end class

1 个答案:

答案 0 :(得分:0)

一些澄清......通过阅读代码,我唯一看到的是你的类WellParameters实现了Interfaces FocusListener和ActionListener(不是静态类)。据我所知,从代码中可以看出,方法 focusGained(FocusEvent e) focusLost(FocusEvent e)是从前一个接口实现的,并更新了静态类,您将依赖于ActionListener事件 actionPerformed()中的相同计算值。您在这里遇到的问题是关于静态实例值的竞争条件。

  

http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html   A.3.4无法访问

     

对象进入无法访问状态   当没有更强烈的引用它   存在。当一个对象无法访问时,   它是收藏的候选人。注意   措辞:仅仅因为一个对象   收集候选人没有   意味着它会被立即收集。   JVM可以自由延迟收集   直到迫切需要   被消耗的内存   宾语。重要的是要注意到这一点   不仅仅是任何强有力的参考   在内存中保存一个对象。这些必须   是来自a的链接的引用   垃圾收集根。 GC的根源是   一个特殊的变量类   包括

     

  • 堆栈上的临时变量(任何线程)   
  • 静态变量(来自任何类)   
  • 来自JNI本机代码的特殊引用

  • 基于此垃圾收集文档,我怀疑您的类 KillWellCalculations 的所有静态引用都有资格在调用FocusEvent方法后进行垃圾收集,因此,在事件 actionPerformed()被触发时,它们不可用。

    只有当其他类使用此类时,您仍然可以将类KillWellCalculations的静态方法用作实用程序类。如果没有,您可以将其转换为包含计算的Value类,不包含静态引用。因为你需要引用一个包含计算值的类的实例...例如:

    public Class CalculatedValues {
         private int measuredDepth;
         private double mudInActivePits;
    
         public static CalculatedValues makeNew() {
              return new CalculatedValues();
         }
    
         public void setMeasuredDepth(String measuredDepthTString) {
               if (measuredDepthTString == null) {
                    throw new IllegalArgumentException("The measured depth must be provided.");
               }
               try {
                    this.measuredDepth = Integer.parseInt(measuredDepthTString);
               } catch(NumberFormatException nfe) {
                    throw new IllegalArgumentException("The value provided is not an interger.");
               }
         }
         public int getMeasuredDepth() {
              return measuredDepth;
         }
    
         public void setMudInActivePitsT(String mudInActivePitsTString) {
               if (mudInActivePitsTString == null) {
                    throw new IllegalArgumentException("The measured mudInActivePits must be provided.");
               }
               try {
                    this.mudInActivePits = Double.parseDouble(measuredDepthTString);
               } catch(NumberFormatException nfe) {
                    throw new IllegalArgumentException("The value provided is not an double.");
               }
         }
         public double getMeasuredDepth() {
              return mudInActivePits;
         }
    
         //...
         //...
         // MORE THE OTHER VALUES/PROPERTIES IMPORTANT/NEEDED BY THE CALCULATION. 
    
         public void doAllCalculations() {
              // YOU HAVE TO IMPLEMENT THE LOGIC FOR THOSE ONES, OPTIONALLY USING THE SAME UTILITY/HELPER STATIC METHODS FROM 
              setPressureBeforeCasingBurstAndFormationFracture();
              setCirculatingPressures();
              setTriplexPumpCapacity();
         }
    }
    

    然后,修改类的构造函数以获得值object的实例:

    ... 
    ...
    // THE VALUE OBJECT REFERENCE WITH THE VALUES YOU NEED TO HOLD DURING THE FORM INTERACTION
    private CalculatedValues calculatedValues;
    
    WellParameters() {  
        super("Well Parameters", true, true, false, true);
        this.setBounds(0, 0, 600, 385);
        this.setVisible(true);
        this.setLayout(new BorderLayout());
    
        ...//GUI Stuff
    
        this.add(submitButtonPanel, BorderLayout.SOUTH);
    
        // THE VALUE OBJECT REFERENCE...
        calculatedValues = CalculatedValues.makeNew();
    }
    

    然后,用计算更新参考:

    @Override
    public void focusLost(FocusEvent e) {
        try {
            if(e.getSource() == measuredDepthT) { 
                //KillWellCalculations.measuredDepth = Integer.parseInt(measuredDepthT.getText());
                // the exceptions thrown can be caught in the catch below and you can display the error message from the value class.
                calculatedValues.setMeasuredDepth(measuredDepthT.getText());
    
              ...//Others 
    
                // collect other values as well...
    
            } else if(e.getSource() == mudInActivePitsT) {
                //KillWellCalculations.mudInActivePits = Double.parseDouble(mudInActivePitsT.getText());
                // do try/catch for the possible runtime exception and display an error message
                calculatedValues.setMudInActivePitsT(mudInActivePitsT.getText());
    
            }
        } catch (Exception ignore) { 
        }
    
    }
    

    最后一步的更新也使用实例引用:

      @Override
        public void actionPerformed(ActionEvent e) {
          try {
            if(e.getSource() == submitButton) {
            System.out.println(KillWellCalculations.pumpEfficiency);
            // THE REFERENCES THAT THIS STATIC METHOD USE WERE ALL GARBAGE-COLLECTED AT THE TIME OF THE CALL... IF SHOULD HAVE THE CALCULATED METHODS IN THE VALUE CLASS. SOMETHING LIKE THE FOLLOWING:
            // KillWellCalculations.setPressureBeforeCasingBurstAndFormationFracture(); //Doesn't work
            //KillWellCalculations.setCirculatingPressures();
            //KillWellCalculations.setTriplexPumpCapacity();
            //System.out.println(KillWellCalculations.mudInActivePits);
            //System.out.println(KillWellCalculations.pumpFactor);
            //System.out.println(KillWellCalculations.finalCirculatingPressure);}
    
            // DO THE FINAL CALCULATION IN A SINGLE METHOD IN THE VALUE OBJECT.
            calculatedValues.doAllCalculations();
    
            // HERE ARE THE GETTERS FROM THE CALCULATED VALUES OF THE DO ALL CALCULATIONS YOU HAVE TO IMPLEMENT.
            System.out.println(calculatedValues.getMudInActivePits());
            System.out.println(calculatedValues.getPumpFactor());
            System.out.println(calculatedValues.getFinalCirculatingPressure());}
    
            // CONSIDERING YOU'RE DONE WITH THE VALUES, JUST CLEAR THE INSTANCE VALUES
            // AS THIS REFERENCE IS NOT STATIC AND IT WILL NOT BE GARBAGE-COLLECTED. 
            calculatedValues.clearValues();
        }
        catch(Exception ignore) {}
      }
    

    我做了一些与GUI相关的工作......您可以在http://code.google.com/p/marcellodesales-cs-research/source/browse/trunk/grad-ste-ufpe-brazil/ptf-add-on-dev/src/br/ufpe/cin/stp/ptfaddon/view/swing/execution/JWizardInternalFrame.java看到一个非常相似的例子

    祝你好运!