Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该在重用方法外部还是内部声明变量?_Java - Fatal编程技术网

Java 我应该在重用方法外部还是内部声明变量?

Java 我应该在重用方法外部还是内部声明变量?,java,Java,(我以字符串为例,但它可以替换为对象>MB的内存) 经常这样做: private static String mTempString = ""; private static void SomeMethod() { mTempString = "Whatever Result"; } 现在我的问题是,如果我这样写的话: private static void SomeMethod() { String mTempString = "Whatever Result"; } 在

(我以字符串为例,但它可以替换为对象>MB的内存)

经常这样做:

private static String mTempString = "";

private static void SomeMethod()
{
    mTempString = "Whatever Result";
}
现在我的问题是,如果我这样写的话:

private static void SomeMethod()
{
    String mTempString = "Whatever Result";
}
在循环中使用它(以每秒执行数百次为例),Java知道如何管理内存吗?将是相同的内存。(很抱歉,我现在无法亲自测试)

哪个内存效率更高(忽略它们是小变量的事实)

--编辑---
在这里找到一篇很好的文章来解释它

一般来说,我更喜欢尽可能地限制变量的范围。这使得代码更容易理解、调试和重构

在这种情况下,这两种情况下这些变量所需的内存都非常小。每个变量都是对对象的引用,而不是对象本身。当用作局部变量时,引用可能只占用四个字节

局部变量的范围应始终尽可能小

除非需要范围外的变量,否则最好在范围内声明变量。在这种情况下没有性能差异,但建议最佳编码实践在尽可能小的范围内声明变量。看到这个类似的和流行的吗


另一种情况是使用不可变类型而不是字符串。性能差异很小(可以忽略不计)。在顶部声明会更好一些,因为您不需要在每个循环中初始化变量。但是在字符串中,因为它每次都在创建新对象,所以这在您的情况下不是问题。

如果
mTempString
是只在
someMethod()中需要的临时变量,那么它必须在方法中声明为局部变量,而不能作为类的静态成员。原因是您希望确保没有其他人干扰您的临时变量

如果您在类中声明它,那么您的代码更容易出错,因为您无法确定谁可以修改该变量


在您的示例中,临时变量被声明为静态字段。这使得代码不是线程安全的。如果两个不同的线程几乎同时调用同一个方法,则第二个方法调用将更改临时变量的值,该临时变量会影响调用第一个调用的线程。

请尽可能缩小变量的范围。

这一点很重要,原因如下:

  • 可读性。如果你在三个不同的地方用四个不同的值使用该变量(见图),你将很难辨别该变量的用途

  • 错误。如果将单个变量保留在一个指定的范围内,可以减少应用程序中可能出现的错误数量。假设您有那个字符串,并且您希望它在两个方法中都是某个值,但它是完全不同的

  • 目的的意图。我在可读性部分提到了这一点,但是如果您有一个不断被重新定义的
    静态
    变量,那么它的目的就不清楚了。通常,静态方法和变量可以独立于对象的状态使用,因此如果对象的状态影响静态变量的值,那么意图就会变得混乱

  • 在这一点上,我不会太担心内存效率(除非您有大量字符串,但我想说您有两件事需要担心)*


    *:第一条优化规则:不要这样做。
    第二条优化规则(仅限专家!):不要这样做Jvm应该能够确定这是一个常量,并在必要时对其进行优化,这样您就不必担心这两种样式

    对于算术表达式,JVM可以执行常量折叠优化

    如果您只是对字符串感兴趣,常量字符串存储在字符串池中

    您可能知道,字符串在java中是不可变的

    因此,如果java中有常量字符串,它们将只存储一次,所有引用都将指向该字符串对象

    e、 g

    返回true,因为t和s指向同一字符串对象

    此外,java类有常量池,所有类似的常量都被移动到其中


    从本质上讲,JVM是相当聪明的,我不认为这两个玩具示例中的任何一个都比另一个好,至少在效率方面是这样的。尽管正如其他答案所提到的,您可能应该考虑一些软件设计方面的考虑

    我对此进行了自己的测试,以查看编译器是否在每次迭代中实际创建了一个“新”对象。以下是以下代码的结果:

    private static long mStartedTime;
    
    public static void main(String args[])
    {
        long TotalTime = 0;
        int NumberOfLoops = 7;
    
        for(int i = 0; i < NumberOfLoops; i++)
        {
            mStartedTime = System.currentTimeMillis();
    
            for(float Index = 0; Index < 10000000; Index++)
            {
                test1("wewgwgwegwegwegsd veweewfefw fwefwef wfwefdwvdw wefwe wevwev etbe tbebetbetb evberve");
            }
    
            System.out.println("Program took: " + String.valueOf(System.currentTimeMillis() - mStartedTime) + " to complete.");
            TotalTime += System.currentTimeMillis() - mStartedTime;
        }
    
        System.out.println("Average time taken: " + String.valueOf(TotalTime / NumberOfLoops));
    }
    
    
    public static void test1(String THisIsText)
    {
        String Test = THisIsText;
        Test = Test.substring(1);
    }
    
    private static String mTempString;
    public static void test2(String THisIsText)
    {
        mTempString = THisIsText;
        mTempString = mTempString.substring(1);
    }
    
    私有静态长mStartedTime;
    公共静态void main(字符串参数[])
    {
    长总时间=0;
    int NumberOfLoops=7;
    for(int i=0;i
    他们提出了不同的建议
    private static long mStartedTime;
    
    public static void main(String args[])
    {
        long TotalTime = 0;
        int NumberOfLoops = 7;
    
        for(int i = 0; i < NumberOfLoops; i++)
        {
            mStartedTime = System.currentTimeMillis();
    
            for(float Index = 0; Index < 10000000; Index++)
            {
                test1("wewgwgwegwegwegsd veweewfefw fwefwef wfwefdwvdw wefwe wevwev etbe tbebetbetb evberve");
            }
    
            System.out.println("Program took: " + String.valueOf(System.currentTimeMillis() - mStartedTime) + " to complete.");
            TotalTime += System.currentTimeMillis() - mStartedTime;
        }
    
        System.out.println("Average time taken: " + String.valueOf(TotalTime / NumberOfLoops));
    }
    
    
    public static void test1(String THisIsText)
    {
        String Test = THisIsText;
        Test = Test.substring(1);
    }
    
    private static String mTempString;
    public static void test2(String THisIsText)
    {
        mTempString = THisIsText;
        mTempString = mTempString.substring(1);
    }