Java 中“new”关键字的实际作用是什么?我应该避免创建新对象吗?

2023-11-25

我不久前注册了,尽管自从我开始自学计算机编程以来,我一直在充分利用这个网站,我一直在自学计算机编程,并认为这是我的一个小爱好。

我确实查找过类似的问题,但事实上我找不到我正在寻找的答案。 现在,请注意,在 Java(这是我建议开始使用的语言)中,根据需要声明和实例化变量被认为是良好的编程实践,请考虑以下几行:

class MyClass {
    void myMethod() {
        AnotherClass myObject = new AnotherClass();
        myObject.doStuff();
    }
}

现在,假设我在运行程序时调用 myMethod() 10 次,这是如何工作的?每次都会创建一个新对象吗? myObject 变量每次都会重新分配吗?编译器是否会跳过类似的代码,因为它发现该对象已经创建并且变量 myObject 已经分配给该对象?简而言之:只有当我计划只调用该方法一次时,我才应该编写这样的代码吗? 我知道……我很羞耻,问了这么愚蠢的问题,但请给我一个机会! 提前致谢!

--------------------------- 已编辑 ---------------------- --------

那么现在我应该在得到新答案后编辑这篇文章吗? 顺便说一句...天哪,太快了,非常感谢!哇,这让我很困惑,我想这是因为我一直在自学…… 不管怎样,创建一个不是没有用吗?new AnotherClass对象为myObject每次都有变量?我的意思是,如果我想在整个程序中使用 myObject 变量,我不应该声明它“一劳永逸”吗?也许在另一种方法中,我只会调用一次?因为据我了解,每次我调用myMethod()正在创建一个新对象,从而覆盖 myObject 自己的属性(又名变量),或者我只是在胡说八道?

--------------------------- 已编辑 ---------------------- --------

在从某个我现在不记得的网站上阅读这段代码后,我产生了疑问:

    public class DataBase {

    private static String buf, retString = "\n";
    private static File file = new File("test.txt");

    public static void readText(JTextArea area) {   
        try {
            FileReader fr = new FileReader (file);
            BufferedReader br = new BufferedReader(fr);
            while ((buf = br.readLine()) != null) {
                area.append(buf); 
                area.append(retString);
            }
            br.close(); 
            fr.close();
        }
        catch (IOException e) {
            System.out.println("Exception: " + e);
        }
    }

    public static void writeText(JTextArea area) {
        try {
            FileWriter fw = new FileWriter (file);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(area.getText());
            bw.close(); 
            fw.close();
        }
        catch (IOException e) {
            System.out.println("Exception: " + e);
        }
    }
}

我的意思是,为什么不声明 FileWriter、FileReader、BufferedReader 和 BufferedWriter 就像他们对其他变量所做的那样,在班级中名列前茅吗? 为什么不在构造函数中也初始化它们呢? 为什么每次调用方法时都这样做而不是使用相同的实例变量?


是的,如果你打电话myMethod()10 次它将创建 10 个独特且独立的对象。

The new关键字的作用与它在罐头上所说的完全一样,它创建一个全新的对象,无论该对象是否已经存在。它创建一个新对象,并将对该对象的引用填充到给定的变量中,覆盖该变量保存的任何先前值(对象)。

myObject 变量每次都会重新分配吗?

再说一遍,是的,每次调用该方法时都会重新分配一个新对象。关于这一点的一个有趣的说明是,当您在方法主体本身中定义变量时,该变量不会“真正”重新分配,因此每次方法结束时,它都会删除在其范围内定义的变量。所以它实际上做的是创建 10 个单独的变量并分配 10 个单独的对象,尽管正如我所说,其他变量应该已自动删除,因此它不会使用任何额外的内存。

简而言之:只有当我计划只调用该方法一次时,我才应该编写这样的代码吗?

正如我所说,在上面的示例中,每个对象都会在方法执行结束时被销毁(假设您没有将对象引用分配给方法范围之外的变量),因此在您的示例中,您可以愉快地调用该方法您想要多少次都可以,但每次都不会连接到之前的呼叫。

我意识到我的写作方式可能会令人困惑,所以如果你想让我澄清任何事情,尽管问。

更新答案以反映编辑后的问题

“为什么不像其他变量那样在类的顶部声明 FileWriter、FileReader、BufferedReader 和 BufferedWriter?”

好的,我假设您了解变量实际上并未被调用FileWriter, FileReader, BufferedReader, and BufferedWriter,而是变量类型。他们的名字是fw, fr, br, and bw。如果你不明白我的意思就问吧。毕竟,从现在开始,我将用您所做的名称来引用变量,以使阅读更容易fw只是代表FileWriter无论如何,所以不应该有太多的混乱。

这个问题的关键隐藏在变量本身的名称中。注意它们是如何结束的Reader or Writer这可以为我们提供有关其用途的微妙线索。清楚地FileWriter and BufferedWriter以某种方式与输出有关。通过查看代码,我们发现我们的怀疑是正确的,并且除了在writeText(JTextArea area)这些变量出现的方法。因此,如果变量没有在代码中的其他任何地方使用,那么在使用它们的方法中定义和初始化它们是合乎逻辑的,这不仅使代码更易于阅读,因为我们然后“知道”这些变量仅与该方法相关,而且还具有在方法执行结束时删除这些变量的好处,从而不会留下仅短暂使用的变量。根据这些规则,我们可以说同样如此FileReader and BufferedReader.

观察这个有关变量范围的示例。 (看我在代码中添加的注释)

public class DataBase {

private static String buf, retString = "\n"; // buf & retString - created
private static File file = new File("test.txt"); // file - created

public static void readText(JTextArea area) {   
    try {
        FileReader fr = new FileReader (file); // fr (FileReader) - created
        BufferedReader br = new BufferedReader(fr); // br (BufferedReader) - created
        while ((buf = br.readLine()) != null) {
            area.append(buf); 
            area.append(retString);
        }
        br.close();
        fr.close();
    } // fr (FileReader & br (BufferedReader) - destroyed
    catch (IOException e) {
        System.out.println("Exception: " + e);
    }
}

public static void writeText(JTextArea area) {
    try {
        FileWriter fw = new FileWriter (file); // fw (FileWriter) - created
        BufferedWriter bw = new BufferedWriter(fw); // bw (BufferedWriter) - created
        bw.write(area.getText());
        bw.close(); 
        fw.close();
    } // fw & bw - destroyed
    catch (IOException e) {
        System.out.println("Exception: " + e);
    }
}
} // buf, retString and file - Still exist as long as the object exists

从这个示例中,可以更清楚地了解为什么变量是在方法中定义的,而不是作为实例变量并在构造函数中初始化的。它允许更清晰的代码并且更具可读性。

为什么每次调用方法时都这样做而不是使用相同的实例变量?

这个问题与变量类型有关。我们无法为所有信息重用单个变量,因为类型需要不同。

如果我们从代码中获取所有变量

private static String buf, retString = "\n"; // valid
private static File file = new File("test.txt"); // valid

FileReader fr = new FileReader (file); // valid
BufferedReader br = new BufferedReader(fr); // valid
FileWriter fw = new FileWriter (file); // valid
BufferedWriter bw = new BufferedWriter(fw); // valid

现在我们知道我们不能将与变量类型不同的值放入该变量中,所以像

FileReader fr = new BufferedReader(fr); // Is not valid!

因为类型根本不匹配。

合理?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 中“new”关键字的实际作用是什么?我应该避免创建新对象吗? 的相关文章

随机推荐

  • Android:如何构建像 Android UI 页面上显示的选项卡

    因此 android 不遗余力地构建了这个漂亮的 UI 指南供每个人使用 但我没有看到任何地方显示如何构建这些元素的代码示例 可以在此处找到选项卡的 UI 指南 http developer android com design build
  • char数组的内存分配

    假设你有 struct Person char name int age int height int weight 如果你这样做 struct Person who malloc sizeof struct Person C 如何知道要分
  • 我可以在 Entity Framework Core 中的连接数据库上触发事件吗?

    我有一个 DbContext 可以访问我的 Postgresql DB 但是当连接会话与 DB 启动时 我需要运行一个小 SQL 命令 我需要为每次交互执行此操作 更具体地说 它是一个用于设置记录用户名的会话变量的函数 可以在 EF Cor
  • 如何在不注册的情况下使用 Win32 中的 .Net 程序集?

    我想从 Delphi Win32 应用程序动态加载和使用用 C 创建的 Net 程序集 我的类和接口被标记为 ComVisible 但我想避免注册程序集 这可能吗 附 我在这里找到了链接文本关于该主题的另一个很好的讨论 但它更多地围绕托管
  • 自定义元素的绑定上下文 - 它到底是什么,如何访问父虚拟机

    我在文档中找不到答案 所以我在这里提问 传递给的绑定上下文到底是什么bind自定义元素的方法 它简单地等于路由器当前活动的 ViewModel 至少 这是我到目前为止所发现的 为什么它不是元素的父级 就 DOM 而言 VM 用这个代码 cu
  • 如何弯曲CGMutablePath?

    具有以下形状 我想知道你如何让它像这样弯曲 也类似 我假设所有的圆 线都被打包成一个CGMutablePath 然后对它应用某种曲线 圆弧或四边形曲线 尽管我很难复制它 有谁知道如何做到这一点 在第一个示例中 您从具有多个闭合子路径的路径开
  • 用于处理文件路径的 Qt 类[重复]

    这个问题在这里已经有答案了 可能的重复 Qt 相当于 PathAppend Qt 中有处理文件路径的类吗 特别是我正在寻找像 NET 的 Path Combine 这样的东西 我知道 boost filesystem 中有一个 但我想知道
  • Scala 开关在成功匹配后继续匹配下一个案例

    我该如何在 scala switch 语句中执行一个 case 块后开始执行另一个 case 块 在java中 没有中断的情况 switch step case 0 do something case 1 do something more
  • .dll 文件无法访问

    我正在尝试将 dll 添加到我的项目中 当我 添加引用 并尝试添加它时 它告诉我 无法添加对 的引用 请确保该文件 可访问 并且它是有效的程序集或 COM 组件 顺便说一句 我正在尝试添加 g729 dll 我怎样才能添加dll 你必须re
  • 垂直进度条

    VS 2005 SP3 我曾多次使用进度条 但是 我需要一个垂直的 但是 我找不到任何可以旋转它的属性 进度条是否始终处于水平位置且无法更改 非常感谢 尝试这个 public class VerticalProgressBar Progre
  • PHP 和 MySQL 之间的周数差异

    我有以下查询 SELECT COUNT WEEK date YEAR date FROM myTable GROUP ON YEAR date WEEK date 假设它产生以下结果 32 33 2012 43 34 2012 39 35
  • 将彩色控制台输出捕获到 WPF 应用程序中

    如同这个问题 除了 WPF 应用程序中包含的控制台程序会生成彩色输出 因此如果我能够捕获颜色和文本 那就太好了 这是我的第一个 WPF 程序 我不知道如何查找 修改正确的控件 目前我只是使用一个 TextBox 它可以工作 但只能捕获纯文本
  • 如何配置 Geany 来编译和运行我的 Python 程序?

    在 构建 菜单下 我可以看到 执行 选项 但它是灰色的 唯一可用的选项是 设置包含和参数 当我单击时 两个字段都已填写 我必须在那里写什么 I don t need to configure anything in Geany I just
  • 寻找一种使用 NSArray 作为一堆按钮的插座的方法

    我的用户界面有四个按钮 它们都会共享一些共同的行为 例如跟踪区域创建之类的事情 我正在寻找的是一个解决方案 所以我不必这样做 interface MyController NSWindowController NSButton button
  • 带有选项卡和 Viewpager 的 Android Fragments

    我们正在构建一个如上所示的具有片段嵌套的应用程序 选项卡特色 详细信息选项卡和地图选项卡 详细信息选项卡将有一个幻灯片 就像 查看页面滑块 和下面可滚动的信息 地图选项卡将显示地图 我已经实现了选项卡 地图以及滑块 如上所示 现在我很困惑如
  • 通过 AcceptEx() 连接的套接字的 TCP 关闭

    的文档AcceptEx says 当此操作成功完成后 sAcceptSocket 可以 已通过 但仅限以下功能 ReadFile 写文件 send WSASend recv WSARecv 传输文件 封闭式插座 setsockopt 仅适用
  • 为什么 Tensorflow-gpu 仍然使用 cpu

    我在后端使用带有tensorflow gpu的Keras 我没有安装tensorflow CPU版本 所有输出都显示选择了GPU 但tf正在使用CPU和系统内存 当我运行代码时 输 出是 输出代码 我什至运行了 device lib lis
  • 使用 matlabpool 时出错 - 未定义函数“distcomp.fileserializer”

    我正在尝试使用 MATLAB 中的并行计算工具箱来帮助加速我正在执行的一些密集计算 在我可以使用像这样的结构之前parfor 我需要通过创建一个工人池matlabpool 首先 我只想使用默认的 local只需调用即可配置文件matlabp
  • 应用程序沙盒/iCloud 和 Snow Leopard 向后兼容性

    到目前为止 所有 Mac App Store 开发人员都知道 所有应用程序都必须启用新的 OSX Lion Sandboxing 对于现有应用程序 我们必须在 XCode 4 2 中启用它并设置数据迁移 plist 因此 我现有的 Mac
  • Java 中“new”关键字的实际作用是什么?我应该避免创建新对象吗?

    我不久前注册了 尽管自从我开始自学计算机编程以来 我一直在充分利用这个网站 我一直在自学计算机编程 并认为这是我的一个小爱好 我确实查找过类似的问题 但事实上我找不到我正在寻找的答案 现在 请注意 在 Java 这是我建议开始使用的语言 中