No. They won't be equal to anything because they won't exist. Nothing ever created an instance of Class so there is no instance.
As an analogy you're basically asking, "If I don't build a house, will that house's windows be open or closed?" They will be neither.
When you do this:
Class object = null;
What you have is a variable which can (at a later time) refer to any instance of type Class, but which currently refers to no instance.
is there a way for me to create the object so that all three instance variables are null
Kind of. You can add a constructor which doesn't set those values:
public Class () { }
And you can create an instance of that class via that constructor:
Class object = new Class();
Then you can observe your instance in the debugger to see what those values are. I'm not 100% sure in Java, but it's possible that an int can't be null. Which would make that part of the question kind of moot. (I know it can't in C#, but if it can in Java then ignore this part and carry on.)
An unassigned int local variable would be a compiler error if you try to use it. But this is a class field, not a local variable. In this case it's going to be automatically given its default value, which is generally null for reference types but 0 for primitive numeric types.
No. They won't be equal to anything because they won't exist. Nothing ever created an instance of Class so there is no instance.
As an analogy you're basically asking, "If I don't build a house, will that house's windows be open or closed?" They will be neither.
When you do this:
Class object = null;
What you have is a variable which can (at a later time) refer to any instance of type Class, but which currently refers to no instance.
is there a way for me to create the object so that all three instance variables are null
Kind of. You can add a constructor which doesn't set those values:
public Class () { }
And you can create an instance of that class via that constructor:
Class object = new Class();
Then you can observe your instance in the debugger to see what those values are. I'm not 100% sure in Java, but it's possible that an int can't be null. Which would make that part of the question kind of moot. (I know it can't in C#, but if it can in Java then ignore this part and carry on.)
An unassigned int local variable would be a compiler error if you try to use it. But this is a class field, not a local variable. In this case it's going to be automatically given its default value, which is generally null for reference types but 0 for primitive numeric types.
Let's say I have a class named Class
Given that java.lang.Class already exists, let's not. Let's say you have a class named MyClass.
and I created a new null object:
That's an oxymoron.
null is a reference. It's not an object. It is, in fact, the reference that means 'I refer to no object', and is the only reference that means 'I point at nothing'.
When you write:
MyClass x = new MyClass();
Then x is a treasure map, and new MyClass() is 'create a new treasure chest and bury it in the sand'. The = in the middle says: Update the treasure map named x, so that following it would lead you to the treasure I just made (new X() means: Make new treasure and bury it).
MyClass x = null;
means you have a treasure map named x which is currently blank.
If not, is there a way for me to create the object so that all three instance variables are null?
That would imply a treasure chest of the MyClass treasure type, which has room for some scratches (int a - a number), and which contains a treasure map (the String b variable). If you want to set them all to null, well, you can't - a is a primitive (int) and those aren't treasure maps, they are the actual number. You can't not have one - a cannot be null. At best, a can be 0. b CAN be null. That means there's real treasure, but the treasure contains yet another treasure map (in java it's mostly treasure maps all the way), but that one is blank. That's different from there being no treasure at all.
More generally, the question: "Can I make a new instance of MyClass such that all fields are some value I desire" is the wrong question to ask, perhaps: The general principle is encapsulation: MyClass is an API: It's like the receptionist at a big corp's office. The receptionist decides what services are available. Even if the CEO is available, if the receptionist elects not to answer the question 'can I see the CEO right now please?', then you can't see her.
Your question boils down to: "If I storm into this office and I demand to speak to the CEO, will I be allowed to?" - the only viable answer is: Well, the receptionist would decide, so you'd have to ask him. For classes: Whatever the API lets you do, you can do. But that's all you can do.
If there is no constructor that initializes these fields to null, then, no, you can't.
An "empty object" is pretty ambiguous in java terms. I could interpret that as this:
Object empty = new Object();
which is about the emptiest object you can create.
However in your example,
Name myName = new Name();
That's going to create an object based on whatever code you've put in your default constructor. (Which, i guess if you're setting everything to a default value, is pretty empty)
If Name has a parameterless constructor, sure. Whether or not it's "empty" depends on what that constructor does or what defaults it may have.
How do you define "empty object" anyway?
For example, if you want a variable but don't want it to actually have an object, you can just declare the variable without initializing it:
Name myName;
In this case myName will be null (or "unassigned"? depends on the context), but will be of type Name and can be used as such later (once it's assigned a value).
All the variable itself does is point to a location in memory where the "object" exists. So something like Name myName doesn't "create" an object, it just creates the pointer to a memory location. new Name() actually creates an object by calling its constructor. When used together like in your example, the latter half creates the object and then the former half points to the location in memory where the object exists.
Firstly, you never set an object to null. That concept has no meaning. You can assign a value of null to a variable, but you need to distinguish between the concepts of "variable" and "object" very carefully. Once you do, your question will sort of answer itself :)
Now in terms of "shallow copy" vs "deep copy" - it's probably worth avoiding the term "shallow copy" here, as usually a shallow copy involves creating a new object, but just copying the fields of an existing object directly. A deep copy would take a copy of the objects referred to by those fields as well (for reference type fields). A simple assignment like this:
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = list1;
... doesn't do either a shallow copy or a deep copy in that sense. It just copies the reference. After the code above, list1 and list2 are independent variables - they just happen to have the same values (references) at the moment. We could change the value of one of them, and it wouldn't affect the other:
list1 = null;
System.out.println(list2.size()); // Just prints 0
Now if instead of changing the variables, we make a change to the object that the variables' values refer to, that change will be visible via the other variable too:
list2.add("Foo");
System.out.println(list1.get(0)); // Prints Foo
So back to your original question - you never store actual objects in a map, list, array etc. You only ever store references. An object can only be garbage collected when there are no ways of "live" code reaching that object any more. So in this case:
List<String> list = new ArrayList<String>();
Map<String, List<String>> map = new HashMap<String, List<String>>();
map.put("Foo", list);
list = null;
... the ArrayList object still can't be garbage collected, because the Map has an entry which refers to it.
To clear the variable
According to my knowledge,
If you are going to reuse the variable, then use
Object.clear();
If you are not going to reuse, then define
Object=null;
Note: Compare to removeAll(), clear() is faster.
Please correct me, If I am wrong....
If null were an Object, it would support the methods of java.lang.Object such as equals(). However, this is not the case - any method invocation on a null results in a NullPointerException.
And this is what the Java Language Specification has to say on this topic:
There is also a special null type, the type of the expression null, which has no name. Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type. The null reference is the only possible value of an expression of null type. The null reference can always be cast to any reference type. In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.
I think this can be boiled down to "null is special".
According to the Java spec, null is a type that can be assigned to an object variable (as a value as noted in the comment). You cannot instantiate or create variables of this type though, you must use the literal null provided by the compiler.
A solution such as Option<T> is not a so bad idea. In fact, it has been successfully introduced in Haskell as a Maybe (but I don't know if this is the first time this solution has been used). Maybe monads are common in Haskell programs. Since, other languages have adopted the same system. For instance, Scala has an Option type.
If you don't want to become dependent of Guava, you could use Java 8, which introduces the Optional class.
However, Option/Maybe/… types are more relevant in a functional environment, because what you typically want to do is to get a behaviour/a property from the element if it really exists, and to get nothing or a default behaviour/property otherwise. So, a typical use of Options consists in
- applying a function A->B on the
Option[A]in order to get anOption[B]; - switching your code on the basis of the real content of the Option (for instance, by using Pattern matching if the language supports it and if Option has two subtypes, or by using method overload);
- or filtering the Options that represent (non-)existing elements.
As an alternative, you could use the Null Object Pattern, in which you have an abstract class MyClass and two concrete subclasses: MyRealClass and MyNullClass. You manipulate instances of MyClass, but generate instances of MyRealClass (if the element is really existing) or MyNullClass (if the element doesn't exist). MyNullClass contains the default behaviours/properties. If the null objects are stateless (which is typically the case), one could cache them, or even make them singletons.
This pattern is described in [Fowler].
[Fowler] Martin Fowler, Kent Beck, Refactoring: Improving the Design of Existing Code.
The whole point of a value object is that equality isn't based on identity; you could very well have two distinct blank objects. In fact, whether all blank objects are the same or different objects should be an implementation detail. For those reasons, the second approach is not good. If you look at the Java 8 APIs, there's a notion of a "value-based class" with the following properties:
- are final and immutable (though may contain references to mutable objects);
- have implementations of equals, hashCode, and toString which are computed solely from the instance's state and not from its identity or the state of any other object or variable;
- make no use of identity-sensitive operations such as reference equality (==) between instances, identity hash code of instances, or synchronization on an instances's intrinsic lock;
- are considered equal solely based on equals(), not based on reference equality (==);
- do not have accessible constructors, but are instead instantiated through factory methods which make no committment as to the identity of returned instances;
- are freely substitutable when equal, meaning that interchanging any two instances x and y that are equal according to equals() in any computation or method invocation should produce no visible change in behavior.
The documentation further adds:
A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class, whether directly via reference equality or indirectly via an appeal to synchronization, identity hashing, serialization, or any other identity-sensitive mechanism. Use of such identity-sensitive operations on instances of value-based classes may have unpredictable effects and should be avoided.
There's no way to disable the == operator in Java so that warning is the best you can do.
Thus, your first approach is correct, with the caveat that foo1.equals(foo2) should always be true when foo1.isBlank() and foo2.isBlank() even if foo1 != foo2.
No, because a is a reference (not an object as in this question's title) and no method can modify the value of a reference except the method in which it is defined (I assume from the code context that a is a local variable).
Since Java doesn't have pass-by-reference, what you ask cannot be done: there's no way to collect addresses-of references in order to manage the addresses pointed to. You might use a wrapper object, but not sure what'd be the point.
As everyone else has said, this simply isn't possible. If it's cleaning up resources you're after, then you might consider using a pattern such as:
class A {
private boolean cleanedUp;
public void cleanUp() {
// clean up any resources
cleanedUp = true;
}
public boolean isCleanedUp() {
return cleanedUp;
}
}
And then using it like so:
A a = new A();
a.cleanUp();
if (a.isCleanedUp()) {
...
}
A better solution might be to implement the java.io.Closeable or java.lang.AutoCloseable interfaces depending on your circumstance:
class B implements AutoCloseable {
private boolean closed;
public boolean isClosed() {
return closed;
}
@Override public void close() throws Exception {
// clean up any resources
closed = true;
}
}
In which case you can use a try-with-resources statement:
try (B b = new B()) {
// do stuff
} catch (Exception ex) {
// oh crap...
}
Or you could even combine the two and do it that way, whichever you prefer.
Or lastly you could do it the way William Morrison explained (though I'd probably cheat and just use java.util.concurrent.atomic.AtomicReference instead of making my own class, and it comes with the added benefit of being a generified type), which, depending on your circumstance, may really be unnecessary. After all, you could always just do (even though it might seem a little odd):
A a = new A();
a.doStuffAndDisappear();
a = null;
if(a == null){
//...
}