[英]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: 每次调用该方法时,他/她可能不希望您创建不同的实例有很多原因,例如:
There are a number of reasons why he/she might want you to create a separate instance each time you invoke that method, eg: 每次调用该方法时,他/她可能希望您创建单独的实例有多种原因,例如:
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. WindowsConsole
, MacConsole
等实例。如果WindowsConsole
和MacConsole
扩展了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.