“new”关键字在Java中实际上做了什么,我应该避免创建新对象? [英] What does the 'new' keyword actually do in Java, and should I avoid creating new objects?

查看:298
本文介绍了“new”关键字在Java中实际上做了什么,我应该避免创建新对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注册了几分钟前,虽然我一直在大量使用这个网站,因为我开始计算机编程,我一直在教自己,并考虑我的一点爱好。



我找了类似的问题,但事实上我找不到我想要的答案。
现在,注意到,在Java(这是我建议的语言开始),它被认为是良好的编程实践,声明和实例化变量,当你需要它们,请考虑以下几行:

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



现在,假设我调用myMethod 10次​​,而我运行我的程序,这是如何工作?是每次都创建一个新对象吗?每次都重新分配myObject变量吗?编译器跳过那样的代码,因为它看到对象已经创建,变量myObject已经分配给这样的对象?简而言之:我应该编写代码,只有当我计划只调用该方法一次吗?
我知道...可耻的问我这样一个愚蠢的问题,但请给我一个机会!
提前感谢!



---------------------------编辑-----------------------------



现在我应该了在我得到新的答案后编辑这篇文章?
btw ... gosh那很快,非常感谢!和哇,困惑我,很多,我想这是由于事实,我一直教自己这样...
无论如何,创建一个不是没有用的新的AnotherClass 每次 myObject 变量的对象?我的意思是,如果我想在我的程序中使用myObject变量,我不应该声明它一次和所有?也许在另一个方法,我将只调用一次?因为根据我的理解,每次我调用 myMethod()一个新的对象是创建,因此重写myObject自己的属性aka变量或者我只是说废话?



---------------------------编辑---------- -------------------



我从某些网站上看到这段代码后发现了我的疑惑,我不记得现在:

  public class DataBase {

private static String buf,retString =\\\
;
private static文件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个唯一和单独的对象。



'new'关键字确实是它在tin上说的,对象,不管是否已经存在。它创建了一个新对象,并且在它给出的变量中引用了该对象,覆盖了变量所保存的任何以前的值(对象)。


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


同样,每次重新分配一个新对象方法被调用。一个有趣的注释是,变量不会真正重新分配,因为你在方法体中定义的变量,所以每次方法结束它将删除在其范围内定义的变量。所以它实际上是创建10个单独的变量和分配10个单独的对象,虽然我说,其他人应该被自动删除,因此不会使用任何额外的内存。



< blockquote>

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


正如我所说,在上面的例子中,每个对象将在方法执行结束时被销毁(假设您没有将对象引用分配给方法范围之外的变量),所以在您的示例中,您可以快乐



我意识到我的写作方式可能会令人困惑,所以如果

'为什么不声明FileWriter? ,FileReader,BufferedReader和BufferedWriter在类的顶部,因为他们对其他变量?'



好吧,我想你明白,变量实际上不是称为FileWriter ,FileReader,BufferedReader和BufferedWriter,而是这是变量类型。他们的名字是fw,fr,br和bw。如果你不明白我的意思只是问。从现在起,我将引用变量的名称,使阅读更容易,afterall fw只是代表FileWriter,所以不应该有太多的混乱。



这个问题的关键是隐藏在变量本身的名称中。注意它们如何结束在 Reader Writer ,这可以给我们一个关于他们的用途的微妙线索。显然, FileWriter BufferedWriter 在某种程度上与输出有关。通过查看代码,我们看到我们的怀疑是正确的,除了 writeText(JTextArea区域)方法,这些变量出现。因此,如果变量不在代码中的任何其他地方使用,那么在它们使用的方法中定义和初始化它们将是合乎逻辑的,不仅使得代码更容易阅读,因为我们知道这些变量仅与该方法相关,而且还具有在方法执行结束时去除那些变量的好处,从而不会留下仅仅使用非常简短的变量。通过这些规则,我们可以说 FileReader BufferedReader 也是如此。



观察这个关于变量范围的例子。 (看看我添加到代码中的注释)

  public class DataBase {

private static String buf,retString =\\\
; // buf& retString - created
private static文件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和file - 只要对象存在,仍然存在

从这个例子中,我们可以清楚地知道为什么变量在方法中定义而不是作为实例变量,并在构造函数中初始化,它允许更清晰的代码以及更多readabe。 p>

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



与变量类型有关。



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

,那么我们不能为所有的信息重复使用单个变量。

  private static String buf,retString =\\\
; // valid
private static文件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); //无效! 

因为类型不匹配。



有意义吗?


I signed up a few moments ago, though I've been making great use of this site since I took up computer programming, which I've been teaching myself and consider a little hobby of mine.

I did look up for similar questions, but in fact I couldn't find the answer I was seeking for. Now, being aware that, in Java (that's the language I was suggested to start off with), it is considered good programming practise to declare and instantiate variables as you need them, please consider the following lines:

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

Now, suppose I invoke myMethod(), say, 10 times while running my program, how does that work? Is a new object create every time? Is the myObject variable reallocated every time? Does the complier skip that like of code as it sees that the object has already been created and the variable myObject already been assigned to such object? In a nutshell: should I write code like that only if I plan to invoke that method only once? I know... shame on me for asking such a stupid question, but please give me a chance! Thanks in advance!

--------------------------- edited -----------------------------

So now am I supposed to edit this post after I get new answers? btw... gosh that was quick, thanks a lot! And wow that confused me, a lot, I guess that's due to the fact that I've been teaching myself so... Anyways, isn't it useless to create a new AnotherClass Object for the myObject variable every time? I mean, if i want to use the myObject variable throughout my program, shouldn't I declare it Once And For All? maybe in another method, that I'm going to invoke only once? Because as far as I understand, every time i invoke myMethod() a new object is creating, thus overriding myObject's own properties aka variables or am I just talking nonsense?

--------------------------- edited -----------------------------

My doubts came after reading this code from some website I can't remember right now:

    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);
        }
    }
}

I mean, why not declare FileWriter, FileReader, BufferedReader and BufferedWriter at the top of the class as they did for the other variables? and why not initialise them as well maybe in the constructor? Why doing it every time the method is called rather than using maybe the same instance variable?

解决方案

Yes, if you called myMethod() 10 times it will create 10 unique and separate objects.

The 'new' keyword does exactly what it says on the tin, it creates a brand new object, irrespective of whether one already exists. It creates a new object and stuffs the reference to that object inside the variable it has been given, overwriting any previous value (object) the variable held.

Is the myObject variable reallocated every time?

Again, yes it would be re-allocated with a new object every time the method was called. An interesting note about this would be that the variable wouldn't "really" be re-allocated as you are defining the variable within the method body itself, so every time the method ends it will remove the variables that were defined within its' scope. So what it actually does is create 10 individual variables and assign 10 individual objects, although as I said the others should have been removed automatically so it wouldn't use any additional memory.

In a nutshell: should I write code like that only if I plan to invoke that method only once?

Well as I said, in the example above each object would be destroyed at the end of method execution (assuming you didn't assign the object reference to a variable outside the scope of the method) so in your example you could happily call the method as many times as you wanted but each time would in no way be connected to the previous calls.

I realise my way of writing can be confusing, so if you want me to clarify anything just ask.

Updated Answer to reflect edited question

'why not declare FileWriter, FileReader, BufferedReader and BufferedWriter at the top of the class as they did for the other variables?'

Okay, I assume you understand that the variables are not actually called FileWriter, FileReader, BufferedReader and BufferedWriter but rather this is the variable type. Their names are fw, fr, br and bw. If you don't understand what I mean just ask. From now on I will refer to the variables by the names you did to make reading more easy, afterall fw just stands for FileWriter anyway so there should not be too much confusion.

The key to this question is hidden within the names of the variables themselves. Notice how they either end in Reader or Writer this can give us a subtle clue about their uses. Clearly FileWriter and BufferedWriter are to do with output in some way. By looking over the code we see that our suspicions were right and that at no point other than within the writeText(JTextArea area) method do these variables appear. So if the variable aren't used anywhere else within the code it would make logical sense to define and initialise them within the method that they are used in, not only does it make the code easier to read because we then "know" those variables are only related to that method, but also has the benefit of those variables being removed at the end of method execution, thereby not leaving variables in existence that were only used very briefly. By these rules we can say the same is true of FileReader and BufferedReader.

Observe this example about variable scope. (Look at the comments I added to the code)

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

From this example it becomes more clear as to why the variables are defined in the methods rather than as instance variables and initialised within the constructor. It allows for much cleaner code as well as being more readabe.

Why doing it every time the method is called rather than using maybe the same instance variable?

Well this question has to do with variable types. We couldn't reuse a single variable for all the information as the types would have needed to be different.

If we take all the variables from the code

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

Now we know that we cannot place a value that is not of the same type as the variable into that variable so something like

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

Because the types simply don't match.

Make sense?

这篇关于“new”关键字在Java中实际上做了什么,我应该避免创建新对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆