AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77673480
Accepted
user2153235
user2153235
Asked: 2023-12-17 14:19:19 +0800 CST2023-12-17 14:19:19 +0800 CST 2023-12-17 14:19:19 +0800 CST

当构造函数创建一个新实例时,为什么 Java 需要“new”[重复]

  • 772
这个问题在这里已经有了答案:
java中的new关键字是多余的吗? (5 个回答)
java为什么要有new?[重复] (6 个回答)
10 小时前关闭。

我在网上搜索了Java中“new”的用法,它是用于创建一个全新的类实例。为什么需要通过“new”关键字明确指示?难道不明白构造函数调用会实例化一个新对象吗?例如,如果没有new,很明显会MyClass AnInstance = MyClass(AnArgument)创建一个新对象。

从实际角度来看,我提出这个问题的原因是因为我认为“新”是为了防范危险而设计的,并且我想了解这种危险。

java
  • 4 4 个回答
  • 133 Views

4 个回答

  • Voted
  1. WestCoastProjects
    2023-12-17T14:39:12+08:002023-12-17T14:39:12+08:00

    冒着一个答案被认为是“意见”的风险,我会抛弃java紧随 C 和 C++ 之后的内容,并本质上继承了后者的语法 - 尽管destroy考虑到垃圾收集器,类似的东西是不必要的。

    因此,对于它没有严格的“要求”,new而是遵循它最强烈派生的语言的模式。

    • 7
  2. ruakh
    2023-12-17T14:54:23+08:002023-12-17T14:54:23+08:00

    例如,如果没有new,很明显会MyClass AnInstance = MyClass(AnArgument)创建一个新对象。

    是吗?

    考虑这个类(它是真正有效的 Java):

    class ClientOfMyClass {
        // define a method named 'MyClass' that is not a constructor:
        static SubclassOfMyClass MyClass(final String arg) {
            return null;
        }
    
        String AnArgument = "hello";
        MyClass AnInstance = MyClass(AnArgument);
    }
    

    在这种情况下,MyClass(AnArgument)调用此类中命名的方法MyClass,并且从未实际创建 的实例MyClass。

    我认为您的错误在于认为这new MyClass(AnArgument)是调用名为 的构造函数的语法MyClass。我认为事实并非如此。MyClass相反,它是通过调用适当的构造函数来创建 的实例的语法。事实上,定义构造函数的语法涉及重复类名;但我认为我们不应该将其视为构造函数名称。请注意,new MyClass.MyClass(AnArgument)即使构造函数不在范围内,我们也不会编写,并且请注意,它作为类的类型参数new MyGenericClass<T>(AnArgument)传递,而不是其构造函数(因为构造函数没有类型参数)。TMyGenericClass

    • 6
  3. Best Answer
    rzwitserloot
    2023-12-17T15:28:05+08:002023-12-17T15:28:05+08:00

    这是命名空间的问题。

    在java中,方法和字段可以具有相同的名称,并且它们完全不相关。事实上,类型也可以,包也可以。所有 4 个都是完全正交的。这 4 者永远不会相遇:

    package foo;
    
    public class foo {
      int foo;
    
      public foo() { /* constructor */ }
    
      public void foo() { /* method */ }
    }
    

    这是完全合法的。这里没有任何内容会覆盖任何内容 - 这是一个foo在 package 中命名的类foo,有 3 个成员:一个名为 的字段foo、一个采用零参数的构造函数,以及一个foo不采用任何参数且不返回任何内容的方法。你可以编译它。它会。没有任何警告。您的 IDE 可能会抱怨以小写字母开头的类型是非常规的。但这只是惯例。lang 规范允许这样做。javac将编译上面的就好了。

    那么,如果你可以将所有这些东西都命名为同一个东西,那么它是如何工作的呢?

    从上下文中java总是知道你在做什么。

    在某些语言中,调用方法时括号是可选的,或者至少所有内容都位于同一名称空间中。

    例如,在 JavaScript 中:

    function test() {
    }
    
    var x = test;
    

    是合法的;x现在是对该函数的引用test。

    事实上,这也意味着你不能在 javascript 中拥有同名的方法和变量:

    function test() {
    }
    
    test = 5;
    test();
    

    不起作用。最后一条语句尝试将“5”作为函数执行,但事实并非如此。

    在java中,情况并非如此(这些括号不是可选的,没有括号,它就与该方法无关,句号),因为java在具有4个完全不相关的名称空间方面有些独特。

    因此,为什么new 必须存在。因为如果它不存在,java 将不知道要挖掘 2 个相关命名空间(类型和方法)中的哪一个。换句话说,这个:

    public class Test {
      public Test() {}
      public static void Test() {}
    }
    

    是合法的java。它编译得很好。那么,如果导入这个 Test 类,然后写:Test();,我在谈论哪一个?

    在java中,很清楚:如果你写new Test(),它就是构造函数,如果你写Test(),它就是静态方法。

    我们可以详细讨论拥有正交命名空间是否是一个明智的想法。然而,java 不喜欢破坏向后兼容性,在这一点上,改变这一切显然不值得所带来的痛苦,所以你的问题将归结为:“为什么 java 的设计者决定使用正交命名空间30 年前”,这……在这样的问题中很难回答,我需要一根鞭子和一顶棕色帽子,还有一些约翰·威廉姆斯的音乐。

    在类级别,这些构造函数被编译为特殊方法,其行为大多类似于静态方法(因为它们不进行虚拟查找,并且不需要接收器 - 它与静态方法共享的属性,但不与实例方法共享),命名为<init>. 不Test,或者不管你的班级叫什么名字。

    所以,最好考虑一下它们(因为这实际上是它的工作原理):

    • 构造函数就是构造函数。它们与类型相关联。他们没有名字。
    • 要编写构造函数,您需要重复类型名称并且根本不添加任何返回类型(甚至不添加void- 或者您正在声明一个方法!) - 但这只是为了让编译器知道您在做什么。将类型名称的重复视为 java 避免引入关键字的方法(它也可能代替public constructor(String arg1, int arg2),public TypeNameGoesHere(String arg1, int arg2)但是,事实并非如此。再说一遍,30 年,如果我们想深入了解原因,请避开一些蛇)。

    注意:命名空间实际上确实满足。它位于 select AST 链中:a.b.c.d.e不明确:是 package a.b,然后是 type c,具有名为 的静态内部类型d,并且具有名为 的静态字段吗e?或者它是a包含类b、内部类c、静态字段的包d,其中的类型z具有名为 的实例字段e?

    Javac 在编译过程中在黑暗中进行了最猛烈的尝试,并将其“锁定”。在运行时(类文件)级别,命名空间确实无法满足。每条指令都清楚地表明标识符所指的是 4 个命名空间中的哪一个。

    • 6
  4. Ankit Kumar Maurya
    2023-12-17T14:43:46+08:002023-12-17T14:43:46+08:00

    据我所知,第一个原因是java语言的语法,需要使用new关键字来创建对象。其次,从技术上讲,new 关键字调用类的构造函数来创建其对象并返回。这种方式允许我们使用私有构造函数(对于单例类),而不能使用 new 关键字来创建对象。

    • -1

相关问题

  • Lock Condition.notify 抛出 java.lang.IllegalMonitorStateException

  • 多对一微服务响应未出现在邮递员中

  • 自定义 SpringBoot Bean 验证

  • Java 套接字是 FIFO 的吗?

  • 为什么不可能/不鼓励在服务器端定义请求超时?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve