【问题标题】:How can I use a non-static (dynamic instance) object as return for a static method in Java? [closed]如何使用非静态(动态实例)对象作为 Java 中静态方法的返回值? [关闭]
【发布时间】:2015-08-16 14:38:13
【问题描述】:

我已经搜索了 stackoverflow 以及其他一些网站,遗憾的是没有发现这个问题,更不用说回答了。也许我的方法最好尝试另一种方式?我是 Java 新手;我认为这应该是一个非常简单的答案。

问题: 我有一个 static 方法,我想从中返回值。为了方便和整洁,我想使用我自己的类而不是 ArrayListString[] 或类似的。问题是我无法在静态方法中实例化我的类(正如我预期的那样可能是一个问题)。有趣的是:使用 String[]Object 作为返回确实有效(这是这些类的一个实例)......所以我为什么不能使用我自己的类实例?

示例:

public static String[] decodeText(String codeString) {
    //Parse codestring and return values (not included in this example)
    String[] data = new String[3];
    data[0]="This";
    data[1]="does";
    data[2]="work";                
    return data;
}

上面的效果很好,但是当我使用自己的类返回值时,编译器给了我“非静态变量 this 不能从静态上下文中引用”(注意:已编辑表明这些类嵌套在 JInputs 类中,这显然是重现错误所必需的):

public class JInputs extends JOptionPane {    
    //A lot of missing code here (which shouldn't be necessary to reproduce issue)

    public class UserData {
        public String userName;
        public String code;
        public long milliTime;

        UserData() {            
        }
        UserData(String userName, String code, long milliTime) {
            this.userName = userName;
            this.milliTime = milliTime;
            this.code = code;
        }
    }

    public static UserData decodeText(String codeString) {
        //Parse codestring and return values (not included in this example)
        UserData data = new UserData();
        data.milliTime = System.currentTimeMillis();
        data.code = "blah";
        data.userName = "Me";                
        return data;
    }
}

显然,我可以将我的 UserData 类设为静态类,但随后对该方法的调用不会更改原始调用的值吗? Java 程序员如何从静态方法返回整洁的数据?为什么它允许实例化内置类而不是用户定义的类?

【问题讨论】:

  • 请查看已编辑的问题——该错误现在应该可以重现了。谢谢!

标签: java static return


【解决方案1】:

这段代码唯一的问题是一个错位的大括号:

public class UserData {
    public String userName;
    public String code;
    public long milliTime;

    UserData() {            
    }
    UserData(String userName, String code, long milliTime) {
        this.userName = userName;
        this.milliTime = milliTime;
        this.code = code;
    }
} //end of class!

//this method is outside the class!
public static UserData decodeText(String codeString) {
    //Parse codestring and return values (not included in this example)
    UserData data = new UserData();
    data.milliTime = System.currentTimeMillis();
    data.code = "blah";
    data.userName = "Me";                
    return data;
}

我想你想要的是这样的:

public class UserData {
    public String userName;
    public String code;
    public long milliTime;

    UserData() {            
    }
    UserData(String userName, String code, long milliTime) {
        this.userName = userName;
        this.milliTime = milliTime;
        this.code = code;
    }


    public static UserData decodeText(String codeString) {
        //Parse codestring and return values (not included in this example)
        UserData data = new UserData();
        data.milliTime = System.currentTimeMillis();
        data.code = "blah";
        data.userName = "Me";                
        return data;
    }
}

上面的方法很好,但是当我使用我自己的类返回值时,编译器给了我“不能从静态上下文引用的非静态变量”

您发布的代码不会导致该错误。您要么复制了错误的代码,要么正在查看旧错误。

显然,我可以使我的 UserData 类成为静态类,但随后对该方法的调用不会改变原始调用的值吗?

确实没有您描述的“静态类”的概念。静态类只是一个内部类,无需外部类的实例即可访问。它的所有成员仍然像普通类的成员一样行事。

Java 程序员如何从静态方法返回整洁的数据?为什么它允许实例化内置类而不是用户定义的类?

您发布的内容可以正常工作。 Java 不区分“内置”类和“用户定义”类。

【讨论】:

  • 有趣...不,我确实希望该类只是数据的容器- decodeText 方法是不同类的一部分,并且仅与它返回 UserData 类型的数据相关。这是否允许外部类引用和使用 UserData 类(如果保持公开)?虽然不是我所期待的,但这可能是实现我想要的最好的方式?感谢您的回复!
  • @DatuPuti 您可以将整个 decodeText() 函数复制到另一个类中,它会正常工作。您发布的代码不会产生您所描述的错误。
  • 嗯......它仍然对我有用。可能我没有给你足够的信息,因为这都包含在基类中,如下所示: public class JInputs extends JOptionPane { public class UserData { ///etc.... } }
  • @DuPuti 我敢打赌,在复制粘贴步骤中会丢失一些东西。您发布的代码对我来说很好,无论是我发布它的方式还是在不同的课程中。我怀疑您的实际代码包含您发布的代码没有的错误-您在复制过程中修复了自己的错误!
  • @DatuPuti 如果UserData 类在另一个类中,并且您想以这种方式使用它,则应将其标记为static,如下所示:public static class UserData { ... }。否则,非静态的内部类期望始终具有对封闭类的引用。
【解决方案2】:

看你遇到的错误,你的问题可能漏掉了一些代码,大概是这样的:

public class SomeClass {
      public class UserData {
            ....
      }

      public static UserData decodeText(String codeString) {
            UserData data = new UserData();
            ....
      }
}

内部类

所以您使用的是内部类的概念。这些类需要能够访问要创建的父类的实例(这里 UserData 需要能够访问 SomeClass 的实例)。当通过“this”指针从非静态方法中创建内部类时,JVM 提供了这种访问。但是,在静态方法中无法访问“this”:这是编译器告诉您的:无法创建 UserData,因为它需要访问 this(“非静态变量 this 无法从静态引用上下文”)。

但是您可以在 SomeClass 或 UserData 及其任何子类的任何非静态方法中创建 UserData 的新实例。

您的用例

在您的情况下,您似乎不需要内部类。当您想要访问父类的成员时,您只需要一个嵌套类。否则一个静态嵌套类就足够了。

您的问题

我可以将我的 UserData 类设为静态类,但随后对该方法的调用不会更改原始调用的值吗?

不,该方法的后续 callq 不会更改先前调用该方法创建的实例的值。静态类并不意味着它的变量是静态的,或者它是singleton。静态类基本上就像一个标准类,只是它嵌套在另一个类定义中。 有关静态和非静态嵌套类之间区别的更多信息,请参阅Oracle documentation

【讨论】:

  • 谢谢!您帮助提供了我需要的概念信息。对于我的教育,我还通过使 UserData 成为它自己的类而不是嵌套类来解决这个问题。那么对于仅用于从方法返回值的小类来说,最好的方法是什么?为每个创建一个类,或者创建一个具有多个静态嵌套类的“ReturnValues”类?或者将它们包含在具有最常用方法的类中?可能是后者,但这可能是一个偏好问题。
  • @DatuPuti 当这个类只在父类中被实例化并且只在其父类的上下文中才有意义时,拥有一个静态类是有意义的。例如 Map.Entry(它是普通的实现 HashMap.Node),在 Map 的上下文之外没有意义,没有人会在它之外创建任何东西。
猜你喜欢
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多