In Java, is new always new? - java

Is there any way in Java that a statement like
Thing thing = new Thing();
could not result in a new object being created (i.e. any way that thing could end up pointing to an already-existing object)?

The new operator allocates new heap space and calls the constructor. You will always get a new object that way (unless, as others pointed out, an Exception is thrown in the constructor).
The thing is a little different with static methods that return a reference, such as Integer.valueOf() which re-uses objects from an internal pool if possible.

If the constructor for Thing throws an exception, the object isn't created. However, thing will never point to another existing instance of Thing.

Several people are saying that an object won't be created if the constructor throws an exception. I would just like to point out that this is not true. As an example, take a look at this very bad code:
public class Test {
static int count;
static Set<Test> set = new HashSet<Test>();
int id = count++;
public Test() {
set.add(this);
throw new RuntimeException();
}
public static void main(String[] args) throws Exception {
for(int i = 0; i < 5; i++) {
try {
new Test();
} catch(Exception e) {
}
}
System.out.println(set);
}
public String toString() {
return "Test[" + id + "]";
}
}
The output is:
[Test[0], Test[1], Test[2], Test[4], Test[3]]
new creates a new object EVERY TIME.

Using new will always result in a new object being allocated and created. However, you might be referring to the concept of interning, where objects and stored in a pool and can be reused to save on space. For a good example, see this article on String interning in Java.

New is always new (maybe with some exceptions for primitive wrappers), but if reusing objects is a desired behaviour there are ways to do that through certain design patterns (singleton, factory, pool etc.).

I'm not sure if I understand your question correctly.
The definition of new is to allocate and initialize a new object.
I guess you might be able store a static reference to a object, and then clone it to make a new object, but that object would still be new.
Since you cannot modify the value of this (otherwise you could just say something like this = oldObject in your constructor), the only way you could do this is to throw an exception, like has been mentioned before.

as far as I know it's not like C++ where you can overload operator new or do placement new or other allocator things. (but I'm not familiar with the JLS)

new always creates new object. In java you can't reuse object using new. Really this leads to performance issue in certain java class. For e.g. Boolean class can practically stores only two values (true or false), still a user can create multiple objects with same value using new.

No, in the case there's no space in memory for it, you should get an OutOfMemoryError.
Of course, there could be other exceptions thrown by the Thing constructor.

No.
After executing that line of code thing will never reference an object that existed before that line.

The call to new can fail if this is the first time you are referring to the class and if the class has static blocks that fail to initialize. I have experienced behaviors wherein any runtime errors that occur in a static block or constructor will result in the new call throwing a ClassNotFound Exception in the context of usage within the websphere application server. The websphere class loader apparently rejects the class from loading because of the runtime exception.

In Java, the only thing I can think of is using the Singleton pattern. This would not create multiple new instances of Thing, but rather an instance of the same object every time.

Related

Java Difference between { Object a = new Object(); a.getVariable() } and { new Object().getVariable() }

i don't know if its asked before (i searched but couldn't find)
Is there any difference between the following 2 code blocks?
1:
// Let's say we want to get variable from non-static object
Object a = new Object();
int varWeWant = a.getVariable();
2:
int varWeWant = new Object().getVariable();
as you see second option is one-line code
and i know the java, both codes create object first and retrieve variable via method but i'm not java expert so i wonder if they have any differences ?
Sorry if it is silly question :D
i was just wondered this for too long
thanx
The first creates an object that can be referred to later, then calls a method on it.
The second creates a temporary object that can only be used to call that single method.
Really, if you're using the second way, you should question if the object was necessary in the first place. It might make more sense to just make that method a standalone function unless you're using the Builder or similar pattern.
both produce the same BUT option 2 is the object instance an anonymous reference... that means you can not do anything with that object after that statement...
int x = new Object().getVariable();
This is done when the object have one time use.
Object a = new Object(); //Creates an object named a
This is done when object has multiple variables and functions. This way object is created only once and the variables and functions are called. If we were to use new Object().getSomeFunction() every time then new object is created every time. Its expensive memory wise and more lines has to be written.
The result in varWeWant is the same.
Some minor differences:
In the first version you can later use the Object for other purposes, as you stored a reference to it in the a variable (that's obvious).
Introducing the variable a comsumes a small amount of memory.
As long as the variable a refers to this Object, the garbage collector cannot reclaim its memory. (But compiler and runtime optimizations might be able to free the memory earlier, as soon as a is no longer used).
Storing the reference in a variable will take a tiny amount of time.

New instance of class created or just space in memory allocated?

UPDATE
public Fish mate(Fish other){
if (this.health > 0 && other.health > 0 && this.closeEnough(other)){
int babySize = (((this.size + other.size) /2));
int babyHealth = (((this.health + other.health) /2));
double babyX = (((this.x + other.x) /2.0));
double babyY = (((this.y + other.y) /2.0));
new Fish (babySize, babyHealth, babyX, babyY);
}
return null;
}
When new Fish is called, is there a new instance of Fish floating around somewhere without a reference or have I just allocated memory for a new Fish without actually instantiating it?
Can I get the new Fish call to create an actual instance of the Fish with a unique reference name other than iterating through a loop?
When new Fish is called, is there a new instance of Fish floating around somewhere without a variable name or have I just allocated memory for a new Fish without actually instantiating it?
A new Fish object will be created, and will be garbage-collected since there is no reference to it.
The garbage collection will take place (sometime) after the constructor of Fish is done.
In your case that doesn't make much sense, but sometimes it does, if instantiating an object will start a new Thread or run some other routines that you want to be run only once.
If I have only allocated memory or there is a Fish without a name, how can I get the new Fish call to create an actual instance of the Fish with a unique variable name?
This is not very clear. But I sense that you just want to return new Fish(...); and assign it to a variable yourself where you call it, something like:
Fish babyFish = femaleFish.mate(maleFish);
"have I just allocated memory for a new Fish without actually instantiating it?"
No. The instance is initialized (the constructor is executed), but if no reference is kept for this instance it will eventually be garbage collected. Keep in mind that a reference can be kept even if your code doesn't do so, for example if the constructor puts this in some static variable.
The following figure's explanation really helped me when I had confusion in the beginning and I hope will help you as well.You can think of Employee as Fish here.
In your case you created a new Fish() object locally inside a method, so the lifetime of that should be assigned locally as well.The garbage collector always looks for unused objects and will identify this suitable for collection as soon as your method exits,along with other locals defined inside the method.
You are returning null, so this method can not be treated as factory method structure since it does not return an instance.I am not sure what you mean by :
Can I get the new Fish call to create an actual instance of the Fish with a unique reference name other than iterating through a loop?
But I think you asked if you can use the exact new Fish() that is inside the method.The short answer is: no. Although you can definitely create another new Fish() but you need a reference variable to retrieve that address or you can return the instance for the method instead of null,which will be a static factory method and is known as a good practice when you want to separately name your constructors.
In a more specific manner to answer both of your updated questions:
1)You did created a new object when you wrote new Fish() but you did not create a reference variable to really retrieve that object information.It's like you have built a house but you don't know the address of the house.Then you can never get to the house. What will happen is because of the lack of retrieval process, this object will be identified as unused by the garbage collector and hence it will be collected.
2)Since there is no reference/pointer or anything to get the information stored in the new object, you cannot retrieve the exact new Fish() inside the method but you can certainly create another object with a reference variable if you really wish to retrieve the information stored in the object.
Lastly, although it is mainly written for C language usage, the following document by Nick Parlante of Stanford University does an exceptional job in explaining references, stack,and heap memories.Click here.
First, let me clear up some confusion in your terminology: An object doesn't have a name. A variable has a name, but you can have many variables of different names all referring to the same object. Having a named variable reference the object does not mean the object has a name.
If you do new Fish() but don't assign the new reference to anything, the new object will be unreachable as soon as the constructor returns.
There is no way to recover that reference, and the object will be unallocated by the next Garbage Collection run.

Create an inline object and pass as parameter

Hi I come from Java where the following is valid:
System.out.println(new String("Hello World"));
is there a C++ equivalent to passing creating an object or pointer in the constructor and pass it as a parameter at the same time such as.
heap.insert(new Food);
Yes. For example
std::vector<Food> c;
c.emplace_back(constructor arguments for Food);
In general, it is most often the case that objects are not given to method as pointers.
If heap.insert takes a const reference :
void insert(const Food& val);
then you can use it with temporary or existing Food arguments, such as
heap.insert(Food{});
var auto foo = Food{constructor arguments};
heap.insert(foo);
heap.insert(Food(constructor arguments));
or in some cases even
heap.insert({constructor arguments});
heap.insert(new Food);
in of itself is valid C++ syntax. It constructs a new instance of the Food class, and passes it to heap's insert() method.
However, the key fundamental difference you will need to learn when transitioning from Java to C++ is that your C++ application is completely responsible for managing all object's lifetimes. In Java you don't need to think about it. Once an object is no longer referenced anywhere, at some point it'll get destroyed by Java's garbage collector.
C++ makes you responsible for managing each object's lifetime. Whenever your application does not need the object that you constructed here with the new operator, it should be deleted, otherwise you're going to leak memory.
To summarize:
heap.insert(new Food);
is just half the story. The new operator will construct your new class instance, and your heap object's insert() method, presumably, stores the pointer to the new class instance, in some fashion. Somewhere, you will then need to delete that class instance, sooner or later.
Yes. You have to define a class, a constructor for it that accepts parameters, then a function that accepts instances of that class and that's all.
Eventually, add to the class definition a proper copy constructor or pass it by reference.
It follows an example:
struct S {
S(int x) { this->x = x; }
int x;
};
void fn(S s) { }
void cfn(const S &s) { }
int main() {
fn(S{42});
cfn(S{42});
}
Be aware that using new in such a case is one of the easiest ways to incur in a memory leak, so pay attention!!
The examples you gave are too easy.
cout << string("hello World");
// not necessary to contruct a string, but to show that it can be done on the spot
heap.insert(Food()); // construct a Food on the spot...
But in general, if you are talking about anonymous classes and similar things in Java, C++ has this stuff, and it has also the lambda concept which is very powerful ;)
If the function parameter is by value or by const reference, and the type you are passing can be used to construct the object, you can pass it directly. For example:
void print(const std::string& str);
int main()
{
print("Hello world");
}
std::string has a constructor which can accept the string literal, and therefore the code compiles, creating a temporary string object, equivalent to:
print(std::string("Hello world"));
If the constructor takes multiple parameters, you can create a temporary object directly in the function call. For example:
void myfunc(const MyClass& c);
myfunc(MyClass(param1, param2));
In Java new objects are creating using new. In C++, new is not required to create a new object, and should be avoided as much as possible, because it makes it harder to avoid memory leaks. This is one of the most common mistakes programmers coming from Java make.
std::string text;
MyClass c;
c.do_something();
This code is totally valid. text and c are valid objects.
std::string *text = new std::string();
MyClass *c = new MyClass();
c->do_something();
delete text;
delete c;
This code is also valid*. But it takes more typing, and if you forget to delete them, you will get a memory leak.
*Edit: Actually it is not exception safe! All the more reason to avoid new!

Java pass and construct class as function argument

I was using a library called Mallet. It is by far the most complicated Java Library I have ever used. They provide tutorials and code template and I was trying to understand it. However, I came across this line of code:
TransducerEvaluator evaluator = new MultiSegmentationEvaluator(
new InstanceList[]{trainingData, testingData},
new String[]{"train", "test"}, labels, labels) {
#Override
public boolean precondition(TransducerTrainer tt) {
// evaluate model every 5 training iterations
return tt.getIteration() % 5 == 0;
}
};
Please don't pay too much attention on the term "transducer". What is passed into this function? Two classes? What is this new String[]{}? I am just very very confused with this syntax as I have never seen it before.
This is the code for this method:
public MultiSegmentationEvaluator (InstanceList[] instanceLists, String[] instanceListDescriptions,
Object[] segmentStartTags, Object[] segmentContinueTags)
Can someone tell me what this weird construct is?
This construct does several things:
Creates a subclass of MultiSegmentationEvaluator without giving it a name
Provides an override of the precondition(TransducerTrainer tt) method
Instantiates the newly defined anonymous class by passing two string arrays and then labels to the constructor that takes four parameters.
Assigns the newly created instance to the evaluator variable.
The code uses the anonymous class feature of Java - a very handy tool for situations when you have to subclass or implement an interface, but the class that you define is used in only one spot in your program.
Consider this code:
String[] stringArr = new String[]{"train", "test"};
Does it make any sense now? It is a String array! =) Here's even more stupid code to prove my point:
new String[]{"train", "test"}.getClass() == String[].class
InstanceList[]
means that you need to have a list of objects that are of they type InstanceList, same goes for String[]
for these:
Object[]
means that anything that is a sublass of Object (any object) can be passed as arguments for the last two paramaters.
In the top code this is exactly what they're doing but they create new objects for InstanceList and String,and then labels is the 2 objects they're passing.

Static method in Java

Looking through some java code and this just does not seem right. To me, it looks like every time you call projects, you will get a new hashmap, so that this statement is always false
projects.get(soapFileName) != null
Seems like it should have a backing field
public static HashMap<String,WsdlProject> projects = new HashMap<String,WsdlProject>();
public Object[] argumentsFromCallSoapui(CallT call, Vector<String> soapuiFiles, HashMap theDPLs,int messageSize)
{
try {
for (String soapFileName:soapuiFiles){
System.out.println("Trying "+soapFileName);
WsdlProject project ;
if (projects.get(soapFileName) != null){
project = projects.get(soapFileName);
} else {
project = new WsdlProject(soapFileName);
projects.put(soapFileName,project);
}
}
} ...
}
Nope. In Java that static variable only gets initialized once.
So, this line will only get called once.
public static HashMap<String,WsdlProject> projects = new HashMap<String,WsdlProject> ();
The projects variable will be initialized once, when the class first loads.
Generally, static maps of this sort are a bad idea: they often turn into memory leaks, as you hold entries long past their useful life.
In this particular case, I'd also worry about thread safety. If you have multiple threads calling this method (which is likely in code dealing with web services), you'll need to synchronize access to the map or you could corrupt it.
And, in a general stylistic note, it's a good idea to define variables using the least restrictive class: in this case, the interface Map, rather than the concrete class HashMap.
You don't call projects - it's a field, not a method.
As it's a static field, it will be initialized exactly once (modulo the same type being loaded in multiple classloaders).
if you add a static initialiser (static constructor?) you'll be able to see that statics are just initialised the first time the class is loaded:
public class Hello {
static { System.out.println("Hello static World!"); }
...
}
You won't get a new HashMap every time you invoke a method on projects, if that's what you are referring to. A new HashMap will be created once, however all instances of the class will share a single HashMap.

Categories

Resources