• Post Reply Bookmark Topic Watch Topic
  • New Topic

The "new" keyword  RSS feed

 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good morning, folks. Just a quick theoretical query on the use of NEW, and when there is a need to have an instance of a class i.e. an Object. Having got a few hundred pages into my first Java book it is clear there are times when NEW isn't required. Looking at the following examples:

1. NEW needed

If a class has non-static variables/methods then you need to create a unique instance to utilise them i.e. an Object.

Using 'd1.' I now have access to all non-static variables and methods within the Dog class (just assume Dog is a valid class). I can now instantiate variables and call methods (which use those variables) on a unique instance of Dog.

2. NEW not needed

Here I have used 'Math.' without creating an instance of Math.

Looking on https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html I'd say the reason there would be no point in creating a NEW instance of the Math class, even if the compiler let you, is that it only contains static elements i.e. static variables and static methods. In other words, class level entities. However, it doesn't of course allow you to create a class because the Math class has a 'Private' constructor. This stops the coder trying to do something there is simply no need to do.

So is this in essence a brief summary of when/where NEW is needed? That is, it is needed if the class you wish to use has non-static elements which would be bound to your use of that instance. If there are only static elements then there is no reason to create an instance as there would be no difference between any of the instances. Additionally coding would usually prevent you from doing so anyway, as in Math, with a Private constructor.
 
Carey Brown
Saloon Keeper
Posts: 3328
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A  bit over simplified. A class can have both static and non-static members. If you want to access the static members you don't need an instance of the class; see String.format(). To access non-static members you'll need an instance to operate on.
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Carey Brown wrote:A  bit over simplified. A class can have both static and non-static members.

Of course it can. However, my query was more about when you would and wouldn't need NEW i.e if there were only static variables/methods you surely wouldn't need/want (be able) to create in instance as there is only class level entities i.e. Math. If a class has either only non-static, OR a mix, and then yes, you'd need an instance to utilise it properly.
 
Carey Brown
Saloon Keeper
Posts: 3328
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clements wrote:... If a class has either only non-static, OR a mix, and then yes, you'd need an instance to utilise it properly.
Not true. You can use String.format() without ever having created a String object.
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Carey Brown wrote:
Paul Clements wrote:... If a class has either only non-static, OR a mix, and then yes, you'd need an instance to utilise it properly.
Not true. You can use String.format() without ever having created a String object.

Ok, but you would only be able to access the static entities i.e. a subset of the methods String has.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another complexity is that the developer may implement *both* the code of the class, and the code that uses the class. So, as shown in your example, it may not be possible to use the new operator (as the constructor is private). It may be possible to call the new operator, and yet, an instance is not needed.

Additionally, it may be possible to need an instance -- and yet, the new operator can't be used. Instances may have to be created via the use of factory methods.

It may be possible to not even know the need too. For example, you can call a method of a class, and the method operation itself, will internally generate and return an instance (if it needs to, such as if it isn't already cached). etc.

Henry
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Carey Brown wrote:A  bit over simplified. A class can have both static and non-static members. If you want to access the static members you don't need an instance of the class; see String.format(). To access non-static members you'll need an instance to operate on.


So is this more accurate:

* Class has only non-static elements - Need an instance i.e. need NEW
* Class has only static elements - Don't need (and shouldn't be allowed) an instance i.e. no NEW needed
* Class has mix of static and non-static elements - Don't need an instance to access static elements. Would need an instance, i.e. NEW, for non-static elements. Your example of String being a classic example of one which could be used at an instance AND class level.
 
Carey Brown
Saloon Keeper
Posts: 3328
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clements wrote:Ok, but you would only be able to access the static entities i.e. a subset of the methods String has.

True. Without an instance you would ONLY be able to access static members.

Depending on your code you can mix and match the use of static and non-static members. When you make use of non-static members you'll need an instance and for static members you don't.
Here, the call to String.format() does not require a String instance to operate on, but s1.length() does.
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Carey Brown wrote:Depending on your code you can mix and match the use of static and non-static members.

This has set me thinking. Looking at String on:

https://docs.oracle.com/javase/7/docs/api/java/lang/String.html

You can see the mix of static and non-static methods i.e. format is static, indexOf is non-static. Can you give a brief explanation of why this is the case? Why is one deemed static and the other not, when on the surface they sort of do a similar thing in that they take in a string and give back a result.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clements wrote:indexOf is non-static. Can you give a brief explanation of why this is the case? Why is one deemed static and the other not, when on the surface they sort of do a similar thing in that they take in a string and give back a result.


It is declared as non-static, because that is how it was designed. The indexOf() method takes a char, and searches the string represented by the instance for that character... or in other words, it is working on the this instance.

If the designers wanted the indexof() method to be declared as static, then technically, it would have been possible too. In that case, the String instance would have to be specified, and likely passed as a parameter.

Heck, it would have been possible to allow both static and non-static forms of the indexof() method, as the two methods would have had to have different signatures anyway... since the static version would have an extra string argument (assuming previous statement).

Henry
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:If the designers wanted the indexof() method to be declared as static, then technically, it would have been possible too. In that case, the string would have to be specified, and likely passed as a parameter

I see what you mean i.e. instance.indexOf() doesn't need a parameter as it gets the value from the heap, not the case if it was static. Hmm, I wonder if this is part of the reasoning. If you are doing something to what's likely to be an existing instance value then there will be a non-static method. If on the other hand you're doing something to a value probably/possibly not in the heap it's static. Perhaps I'm thinking too deep here...lol. I just worry about accepting things at face value without questioning the reasons why. If I do I feel I might be missing something.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clements wrote:I see what you mean i.e. instance.indexOf() doesn't need a parameter as it gets the value from the heap, not the case if it was static. Hmm, I wonder if this is part of the reasoning. If you are doing something to what's likely to be an existing instance value then there will be a non-static method. If on the other hand you're doing something to a value probably/possibly not in the heap it's static. Perhaps I'm thinking too deep here...

I'm afraid all the nitpicking at your reasoning has made you think too deeply and confused you. The part that I bolded above doesn't make sense to me. Everything else you said earlier did make sense in general, IMO, even if it could be picked apart with little "yes, but..."s.

The motivation behind choosing to make an instance method vs a static method is that instance methods operate on information that's unique to an instance of the class. The result of indexOf('a') depends on the state of the current String object. One string may return 4 while another string may return -1, based on what characters are in each of them. Methods like Math.max() and Math.min(), which are static, base all of their workings on information that is passed in via the parameters, hence Math.max(1, 5) will always be 5 and there is no information in the Math class or any information in a hypothetical Math object, if it were possible to create one, that would be needed to get that result. Two distinct instances of Math, if you could create them, would both return 5 if you were to call math1.max(1, 5) and math2.max(1, 5).

One design red flag is actually creating an instance method that doesn't need to know anything about the particular instance on which it is called. That means it should be a static method or that one or more of the arguments to the method should be implied as coming from the current instance. For example, programmers should recognize this code as "smelly":

Anyone who understands "objects" should recognize the silliness of the calculateArea() method above and say that it is more appropriate to have this:

The getArea() instance method needs no parameters because the instance provides all the information it needs to calculate the result.

There are more slightly subtle cases where a design flaw is evident but it's still early and I have to kickstart my brain first to come up with a good example.
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:
Paul Clements wrote:I see what you mean i.e. instance.indexOf() doesn't need a parameter as it gets the value from the heap, not the case if it was static. Hmm, I wonder if this is part of the reasoning. If you are doing something to what's likely to be an existing instance value then there will be a non-static method. If on the other hand you're doing something to a value probably/possibly not in the heap it's static. Perhaps I'm thinking too deep here...

I'm afraid all the nitpicking at your reasoning has made you think too deeply and confused you. The part that I bolded above doesn't make sense to me.


Yes, it wasn't very clear. What I meant was that when using the indexOf method, you don't need to provide the value of the String being tested i.e.

The reason being the String value ("Hello") is an instance value of s1 and therefore on the heap - assuming String as an object holds its instance values on the heap. Yes, of course indexOf needs a param, but the param is the substring being searched for, not the associated String value.
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:

Anyone who understands "objects" should recognize the silliness of the calculateArea() method above and say that it is more appropriate to have this:


Oh, I absolutely get that i.e. why provide params when the instance variables should allow the non-static method to get them for itself.

Think my previous, possibly badly worded, query was why would one String method format being static, while another such as, indexOf would be non-static. Both sort of do the same thing, stuff on a String.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, I knew I had one right at the tip of my tongue. I've been playing around with Conway's Game of Life implementations in Java and the Go language lately, just having facilitated a Code Retreat a couple of weeks and also in preparation for a volunteer mentor gig at a college hackathon event next weekend.

If you're not familiar with the problem of the Game of Life, read up on it first (follow the link above) before you read the rest of this otherwise it won't make sense.

In implementing the Game of Life, it's not uncommon to see programmers write a method that calculates the evolution of the population from one generation to the next. A typical attempt looks like this:

On the surface, the above design looks reasonable. The code actually looks very clean. In fact, there are many programmers who would be hard-pressed to think of how to turn that static void calculateNextGeneration() method into a more appropriate, more elegant, more object-oriented instance method. The subtlety there is that the state of the nextGeneration is calculated based on the state of the currentGeneration. So, a more object-oriented approach would be to define this:

This is way more elegant (and it's not even the best yet, but that's the subject for yet another discussion).
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clements wrote:
Think my previous, possibly badly worded, query was why would one String method format being static, while another such as, indexOf would be non-static. Both sort of do the same thing, stuff on a String.

Well, look at the information that String.format() needs. It has a variable list of arguments at the end to account for any number of format specifiers in the format string. Some of that information may have nothing to do with any particular instance of a String.  The format() method is a static/class method largely because its return type is String. The return type defines the semantics of the method's use. If its return type was something different, like a Formatter object instead maybe, the semantics of its use would change and so it might be more natural to be a static method of the Formatter class.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The Game of Life example is actually also a good example of how good names can help lead you to a better implementation.  In the example code I gave, I had the names thisGeneration and nextGeneration.  It was originally currentGeneration and nextGeneration.  I'm very anal-retentive about symmetry in my code so the longer currentGeneration didn't look as visually appealing to me as the same-lengthed name thisGeneration:

Well, the happy consequence of the above is that I now recognize that the "next generation is calculated from this generation" and I always key off of the this keyword to tell me when I need an instance method.
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:I'm very anal-retentive

Goes with the territory. Don't be ashamed. I'd be concerned if you weren't :-)
 
Knute Snortum
Sheriff
Posts: 4281
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What about:
 
Paul Clements
Ranch Hand
Posts: 99
1
Chrome Eclipse IDE MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Knute Snortum wrote:What about:

A good alternative...lol :-)
 
Carey Brown
Saloon Keeper
Posts: 3328
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
o1.method() vs MyClass.method(o1)

  • Both approaches push o1 on the stack.
  • Both approaches may use the state of o1 in its logic.


  • The first approach requires that o1 be non-null, in the second approach o1 could possibly be passed as null thereby requiring more code to handle that condition.
  • The first approach will use o1 to determine if it needs to invoke an overridden implementation of method(). In the second approach this does not happen.

  • Depending on your design the differences could be deal breakers and guide your choice.
     
    Junilu Lacar
    Sheriff
    Posts: 11494
    180
    Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Paul Clements wrote:
    Knute Snortum wrote:What about:

    A good alternative...lol :-)

    That's missing the point. Besides, the IDE will autoformat that back into misalignment unless you set the feature off in that section of code. The point is that the "current" prefix was changed to "this" and the "this" prefix made me realize that a refactoring to an instance method was probably warranted.
     
    Junilu Lacar
    Sheriff
    Posts: 11494
    180
    Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Carey Brown wrote:o1.method() vs MyClass.method(o1)

  • Both approaches push o1 on the stack.
  • Both approaches may use the state of o1 in its logic.


  • The nuance here is what kind of object is o1. If it is an instance of MyClass, then the static version could be a candidate for changing to an instance method. It all depends on the context of use. Let's stick with the String class and look at all its static methods. You'll notice that none of them explicitly take a String argument. Now, consider if its intern() method were a static method instead with a signature of public static String intern(String). Then the usage would look like this:

    In an object-oriented sense, that smells. It should be

    which is how the method is actually designed. (And let's not nitpick at the validity of doing what that example does in a real program. I've never done that; I'm just using it to compare hypothetical and actual mechanics/design with respect to static vs instance.)
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!