简体   繁体   English

有些类需要初始化,有些则不需要

[英]Some classes need initialization and some don't

I already tried to search for an answer on the "using the new keyword" but didn't found an answer on my specific question. 我已经尝试搜索“使用新关键字”的答案,但没有找到我的具体问题的答案。

Why do some classes have to be created with the keyword new and some don't 为什么有些类必须使用关键字new创建,有些则不需要

For example : 例如 :

import java.io.BufferedReader

If you want to use this you have to create a new instance 如果要使用此功能,则必须创建新实例

BufferedReader read = new BufferedReader (..............)

But for example with system.console which also needs an import java.io.console . 但是例如使用system.console也需要import java.io.console when you want to use this you can just type Console c = system.console() 当你想使用它时你只需键入Console c = system.console()

i'm a beginner in Java and OO programming and found a couple of this examples troughout my book. 我是Java和OO编程的初学者,在我的书中找到了几个这样的例子。

Thx for the help 谢谢你的帮助

In java, fields(aka Attributes) are always associated to either instance or to class. 在java中,字段(aka Attributes)始终与实例或类相关联。

There could be many instances of a class and to create instance you have to use new operator. 可能有很多类的实例,要创建实例,您必须使用new运算符。 To access instance related attributes, you will need to create one and this will be accessed as 要访问与实例相关的属性,您需要创建一个,这将作为访问

ClassName instanceName = new ClassName(); 
instanceName.methorOrAttributeNameGoesHere

For class associated attribute aka Static attribute can be direcly accessed as ClassName.methorOrAttributeNameGoesHere 对于类关联属性,静态属性可以直接访问为ClassName.methorOrAttributeNameGoesHere

These are very basics of Java and probably you should first read some good book on Java and OOP like 'Head First Java' 这些是Java的基础知识,你可能应该首先阅读一些关于Java和OOP的好书,比如'Head First Java'

The simple answer to this is that instantiation like new BufferedReader() always creates a different instance each time you call it; 对此的简单回答是,像new BufferedReader() 这样的实例化每次调用时都会创建一个不同的实例; invoking a method like System.console() might or might not give you different instance. 调用System.console()类的方法可能会也可能不会为您提供不同的实例。

Ultimately, all objects are instantiated via new ; 最终,所有对象都通过new实例化; you just might not see it in your code. 你可能在代码中看不到它。

Here are a couple of ways in which System.console() might be implemented (totally simplified, not actually like it is): 这里有几种方法,其中System.console() 可能会实现(完全简化,实际上并不喜欢它):

// (1) Returns new instance each time
class System {
  static Console console() {
    return new Console();
  }
}

or 要么

// (2) Returns same instance each time
class System {
  private static final Console CONSOLE = new Console();

  static Console console() {
    return CONSOLE;
  }
}

(There are infinitely more ways to implement it, these are just two examples. You can see the way it is implemented in OpenJDK by looking at the source code - it is similar to (2), in that the same instance is returned each time, just with a few more complications that I don't want to describe here) (实现它的方法有很多种,这只是两个例子。你可以通过查看源代码看到它在OpenJDK中实现方式 - 它与(2)类似,因为每次返回相同的实例,还有一些我不想在此描述的并发症)

In (1), if you invoke System.console() twice, you will get back two different instances of Console : 在(1)中,如果您两次调用System.console() ,您将返回两个不同的Console实例:

System.console() != System.console()

In (2), if you invoke System.console() twice, you will get back the same instance of Console : 在(2)中,如果您两次调用System.console() ,您将返回相同的Console实例:

System.console() == System.console()

The question I would ask here is do I need to care if I get back different instances or the same instance? 我在这里要问的问题是,如果我回到不同的实例或同一个实例,我是否需要关心? The answer is probably not , if the API designer has done a reasonable job. 如果API设计师做了一个合理的工作,答案可能不是

The decision as to whether expose the creation of a new Console was made by the person who wrote the classes. 关于是否公开创建新Console是由编写类的人做出的。 There are a number of reasons why he/she might not want you to create a different instance each time you invoke that method, eg: 每次调用该方法时,他/她可能不希望您创建不同的实例有很多原因,例如:

  • The thing you are creating might be very expensive (slow, takes up lots of resources etc), so you don't want to create lots of them; 你正在创建的东西可能非常昂贵(速度慢,占用大量资源等),所以你不想创建它们;
  • The thing you want has logically just one instance (it is a singleton). 你想要的东西逻辑上只有一个实例(它是一个单例)。

There are a number of reasons why he/she might want you to create a separate instance each time you invoke that method, eg: 每次调用该方法时,他/她可能希望您创建单独的实例有多种原因,例如:

  • You don't want all of the places using that instance to share state. 您不希望使用该实例的所有场所共享状态。 You have to worry about things like thread safety when instances of mutable classes are shared. 当共享可变类的实例时,您必须担心线程安全等问题。

And there are a number of reasons why you might not want the user to invoke the constructor directly: 您可能不希望用户直接调用构造函数的原因有很多:

  • new Console() creates an instance of Console exactly ; new Console() 完全创建了Console的实例; things like consoles are often platform-dependent, so you might actually want an instance of WindowsConsole , MacConsole etc to be returned when run on Windows, MacOS etc. If WindowsConsole and MacConsole extend Console , either of these can be returned from the System.console() method. 控制台之类的东西通常依赖于平台,因此您可能希望在Windows,MacOS等上运行时返回WindowsConsoleMacConsole等实例。如果WindowsConsoleMacConsole扩展了Console ,则可以从System.console()返回其中任何一个System.console()方法。
  • Prior to the introduction of the diamond operator <> in Java 7, it was necessary to include the full generic parameters in the new statement, eg ArrayList<HashMap<String, List<String>>> list = new ArrayList<HashMap<String, List<String>>>(); 在Java 7中引入菱形运算符<>之前,必须在new语句中包含完整的泛型参数,例如ArrayList<HashMap<String, List<String>>> list = new ArrayList<HashMap<String, List<String>>>(); ; ; however, generic methods allowed this to be written as ArrayList<HashMap<String, List<String>>> list = newList() : 但是,泛型方法允许将其写为ArrayList<HashMap<String, List<String>>> list = newList()

     <T> List<T> newList() { return new ArrayList<T>(); } 
  • (Sometimes, you need a lot of parameters to pass to the constructor, and it is convenient to use the Builder Pattern . This isn't relevant to the cases in the question, but it is a reason for not invoking the constructor directly.) (有时,您需要将大量参数传递给构造函数,并且使用Builder模式很方便。这与问题中的情况无关,但这是不直接调用构造函数的原因。)

The thing is that these are internal implementation details, and should be encapsulated : you, as a user of the Console class, shouldn't need to care about how expensive it is to create, or whether there is shared state: you just want a Console . 问题是这些是内部实现细节,应该封装 :作为Console类的用户,您不需要关心创建它的成本,或者是否存在共享状态:您只需要一个Console

This encapsulation is effected by providing a method like System.console() : you don't need to know whether the method is implemented like (1) or (2) above (or any other method). 这种封装是通过提供类似System.console()的方法实现的:您不需要知道该方法是否像上面的(1)或(2)那样实现(或任何其他方法)。

Additionally, if the class is originally written like (1), and that proves to be problematic, its implementation can be changed to (2) without you, as a user of the System class, needing to update your code. 另外,如果类最初编写为(1),并且证明存在问题,则可以将其实现更改为(2),而不需要您作为System类的用户更新代码。

This might be a bit too much detail for a beginner, and I can try to help you understand more; 对初学者来说这可能有点太多细节,我可以尝试帮助你理解更多; the long and short of it is that sometimes it is be better if you don't create instances directly. 它的长短是因为如果不直接创建实例,有时会更好。

System.console,console is static thats why we are calling it with class name directly,and to call the non static method we generally used the objectname.methodname . System.console,console是静态的,这就是我们直接使用类名调用它的原因,并且为了调用非静态方法,我们通常使用objectname.methodname。

The java.io.Console class is attached with system console internally.System class provides a static method console() that returns the unique instance of Console class.Thats why we used to do as Console c = system.console() ; java.io.Console类在内部与系统控制台连接。系统类提供了一个静态方法console() ,它返回Console类的唯一实例。这就是我们以前用来作为Console c = system.console()

Please read about Static classes and non static classes method invocation/instance creation for more details. 有关更多详细信息,请阅读静态类和非静态类方法调用/实例创建。

Static methods don't require an instance, but non-static methods do. 静态方法不需要实例,但非静态方法可以。 System.console() is static, but new BufferedReader(...).read(...) is not System.console()是静态的,但new BufferedReader(...).read(...)不是

Static methods are typically used when the outcome of the method will never change based on the context. 当方法的结果永远不会根据上下文改变时,通常使用静态方法。 For instance: 例如:

Math.abs(-3); //will always be 3, no matter what

However consider this class: 不过考虑这个课程:

public class Person {
  private String name;

  public Person(String name){
      this.name = name;
  }

  public String getName() { 
    return name;
  }

  /*
   * In this world, no special characters are allowed in a person's name
   */
  public static boolean isValidName(String name) {
     if (name.contains("!#$%&(=?") {
        return false;
     }
     return true;
  }

}


Person mySister = new Person("Mary");
Person myBrother = new Person("David");

Calling Person.getName() doesn't make any sense; 调用Person.getName()没有任何意义; this is like asking "What is a person's name?" 这就像问“一个人的名字是什么?” without specifying who the person is. 没有说明这个人是谁。 Now if you ask me "What is your sister's name?", then I can call mySister.getName() and give you a sensible answer. 现在,如果你问我“你姐姐的名字是什么?”,那么我可以打电话给mySister.getName()并给你一个明智的答案。


Re: your comment "how do you know when to not use new" 回复:你的评论“你怎么知道什么时候不用新”

If you are trying to create a new Person object (imagine you just had a baby), but you are wondering whether or not that amazing name you found on the internet will be accepted by the authorities: 如果您正在尝试创建一个新的Person对象(想象您刚生了一个孩子),但您想知道您在互联网上找到的这个神奇的名字是否会被当局接受:

boolean validName1 = Person.isValidName("LordVoldeMort!!!!!"); //returns false
boolean validName2 = Person.isValidName("HarryPotter2016"); //returns true

Person myLittleBabySon = new Person("HarryPotter2016"); //Accepted by authorities

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 换行符在某些类中不起作用 - Line breakpoints don't work in some classes 春季建议不适用于某些类的某些方法 - Spring advice don't apply to some methods of the some classes 为什么有些类在创建实例时不需要“New”这个词? - Why some classes don't need the word “New” when creating its instance? 为什么 JDK 中的一些可比较类将比较函数限制为 {−1, 0, 1} 而有些则没有? - Why do some comparable classes in the JDK limit the comparison function to {−1, 0, 1} and some don't? Jackson 注释:有些看得见,有些看不见 - Jackson annotations: some are seen, some don't 只是做了一些练习,遇到了一些问题,不知道是逻辑还是什么。 我需要一双眼睛 - Just doing some exercises and ran into some problems, don't know if its logic or what. I need some eyes 为什么某些android事件停止传播,而其他则不需要? - why do some android events stop propagation and other don't need to? 实体的某些属性需要全文搜索,而其他则不需要 - Some properties of an Entity need full-text search, others don't 需要 BLUETOOTH 权限:我在某些意图 Android Studio 中没有权限 - Need BLUETOOTH permission : i don't have permission in some intent Android Studio 为什么 Spring Boot 项目中的某些依赖项不需要指定版本? - Why you don't need to specify the version for some dependencies in Spring Boot project?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM