Trying to pass only the parent class data from the extended class in a function.
public class ParentClass {
String pageNo;
}
public class ExtendClass extends ParentClass {
String lineNo;
}
In another class i'm trying to
dosomething(...){
savePage((ParentClass)extendClass);
}
savePage(ParentClass pclass){
.....
}
But when i look into the function savePage arguments i can still see lineNo which i don't want to see.
UPDATE
I have added debug pic of the issue i was facing. Even after downcasting to PageApi, i still see "elements" which exist in BoardPage class
It seems to me that what you are trying to achieve is impossible.
If you create an instance of ExtendClass, then that instance always has a lineNo field.
When you explicitly cast or implicitly convert the type ExtendedClass to ParentClass, you don't change the actual instance in any way. At runtime, the instance has that lineNo field ... in all cases. Now the compiler won't let code within the body of the savePage method see or refer to that field (unless the code first casts the reference back to the type ExtendedClass), but the field will be there nonetheless.
You are examining the instances using a debugger. A debugger doesn't follow the rules able what fields should be visible. It sees everything, and it shows you everything. And, it clearly shows you the reality ... that the field is really there.
So ... is there a way to make the field go away entirely? Or hide it from the debugger?
Answers: No, and No.
(Warning: this is tangential to the original question, and probably beyond the OP's understanding.)
Should there be a way to make the field go away? From a language design perspective?
Answer: No.
Consider this code as a "thought experiment":
ExtendedClass ec = new ExtendedClass();
ec.lineNo = 42;
ParentClass pc = (ParentClass) ec; // Actually the cast is redundant
ExtendedClass ec2 = (ExtendedClass) pc;
System.err.println("The old line no is " + ec.lineNo);
System.err.println("The new line no is " + ec2.lineNo);
If (hypothetically) casting from ExtendedClass to ParentClass actually removed a field, then when you cast back to ExtendedClass the field value would no longer be there. But what should ec2.lineNo actually contain? And how could it be different to ec.lineNo ... unless we had actually created a completely new object when we did the type cast(s)?
Thinking it through, if an explicit or implicit type cast created a new object, then you couldn't effectively do polymorphism. Polymorphism depends on being able to operate on a given object from the viewpoints of either its true type or one of its supertypes. If creating that view actually creates a new object ... it simply doesn't work ... unless Java was a pure functional language; i.e. no mutation.
In short, while it might possibly be an attractive idea for a small number of use-cases, this idea would fundamentally break Java as an OO language.
This is my example for the short answer I gave above
import java.lang.reflect.Field;
public class Parenting {
static public class ParentClass {
String pageNo;
public ParentClass() {}
public ParentClass(final ParentClass pOriginal) { // copy CTOR
pageNo = pOriginal.pageNo;
}
}
static public class ExtendClass extends ParentClass {
String lineNo;
}
public static void main(final String[] args) throws IllegalArgumentException, IllegalAccessException {
final ParentClass pc = new ParentClass();
pc.pageNo = "page #7";
final ExtendClass ec = new ExtendClass();
ec.pageNo = "page#24";
ec.lineNo = "line #25";
analyze("Pure Parent", pc);
analyze("Cast Parent", ec);
analyze("Copy Parent", new ParentClass(ec));
}
static private void analyze(final String pTitle, final ParentClass pAnalyzeObject) throws IllegalArgumentException, IllegalAccessException {
System.out.println("Analyzing " + pTitle + ":");
Class<?> p = pAnalyzeObject.getClass();
while (p != Object.class) {
for (final Field f : p.getDeclaredFields()) {
System.out.println("\t" + p.getName() + "\t" + f.getName() + "\t\"" + f.get(pAnalyzeObject) + "\"");
}
p = p.getSuperclass();
}
}
}
Related
I'm trying to make instances of anonymous classes using reflection. But ocassionally I've seen strange behaviour during instantination.
Please, look at these similar fragments of code
public class HideAndSeek {
#SuppressWarnings("unchecked")
public static void main(String[] args) throws IllegalAccessException, InstantiationException{
final String finalString = "I'm final :)";
Object object2 = new Object(){
{
System.out.println("Instance initializing block");
System.out.println(finalString);
}
private void hiddenMethod() {
System.out.println("Use reflection to find me :)");
}
};
Object tmp = object2.getClass().newInstance();
}
}
This code works well, and the output expected
Instance initializing block
I'm final :)
Instance initializing block
I'm final :)
After this I've decided to change code in simple way (just added java.util.Calendar)
import java.util.Calendar;
public class HideAndSeek {
#SuppressWarnings("unchecked")
public static void main(String[] args) throws IllegalAccessException, InstantiationException{
final String finalString = "I'm final :)";
final Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTime().toString()); //works well
Object object2 = new Object(){
{
System.out.println("Instance initializing block");
System.out.println(finalString);
//simply added this line
System.out.println(calendar.getTime().toString());
}
private void hiddenMethod() {
System.out.println("Use reflection to find me :)");
}
};
Object tmp = object2.getClass().newInstance();
}
}
And here is output that I've got:
Wed Aug 17 02:08:47 EEST 2011
Instance initializing block
I'm final :)
Wed Aug 17 02:08:47 EEST 2011
Exception in thread "main" java.lang.InstantiationException: HideAndSeek$1
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at HideAndSeek.main(HideAndSeek.java:29)
As you may see - new instance hasn't been created.
Could anybody explain me, the reason of such changes?
Thanks
This is a very simple question with a very complex answer. Please bear with me as I try to explain it.
Looking at the source code where the exception is raised in Class (I'm not sure why your stack trace doesn't give the line numbers in Class):
try
{
Class[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// removed some code that was not relevant
}
catch (NoSuchMethodException e)
{
throw new InstantiationException(getName());
}
you see that NoSuchMethodException is being rethrown as InstantiationException. This means there is not a no-arg constructor for the class type of object2.
First, what type is object2? With the code
System.out.println("object2 class: " + object2.getClass());
we see that
object2 class: class junk.NewMain$1
which is correct (I run sample code in package junk, class NewMain).
What then are the constructors of junk.NewMain$1?
Class obj2Class = object2.getClass();
try
{
Constructor[] ctors = obj2Class.getDeclaredConstructors();
for (Constructor cc : ctors)
{
System.out.println("my ctor is " + cc.toString());
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
which gives us
my ctor is junk.NewMain$1(java.util.Calendar)
So your anonymous class is looking for a Calendar to be passed in. This will then work for you:
Object newObj = ctors[0].newInstance(Calendar.getInstance());
If you have something like this:
final String finalString = "I'm final :)";
final Integer finalInteger = new Integer(30);
final Calendar calendar = Calendar.getInstance();
Object object2 = new Object()
{
{
System.out.println("Instance initializing block");
System.out.println(finalString);
System.out.println("My integer is " + finalInteger);
System.out.println(calendar.getTime().toString());
}
private void hiddenMethod()
{
System.out.println("Use reflection to find me :)");
}
};
then my call to newInstance won't work because there are not enough arguments in the ctor, because now it wants:
my ctor is junk.NewMain$1(java.lang.Integer,java.util.Calendar)
If I then instantiate that with
Object newObj = ctors[0].newInstance(new Integer(25), Calendar.getInstance());
a peek inside using the debugger shows that finalInteger is 25 and not the final value 30.
Things are slightly complicated because you're doing all of the above in a static context. If you take all your code above and move it into a non-static method like so (remember, my class is junk.NewMain):
public static void main(String[] args)
{
NewMain nm = new NewMain();
nm.doIt();
}
public void doIt()
{
final String finalString = "I'm final :)";
// etc etc
}
you'll find the ctor for your inner class is now (removing my added Integer reference):
my ctor is junk.NewMain$1(junk.NewMain, java.util.Calendar)
The Java Language Specification, section 15.9.3 explains it this way:
If C is an anonymous class, and the direct superclass of C, S, is an
inner class, then:
If the S is a local class and S occurs in a static context, then
the arguments in the argument list, if any, are the arguments to
the constructor, in the order they appear in the expression.
Otherwise, the immediately enclosing instance of i with respect to
S is the first argument to the constructor, followed by the
arguments in the argument list of the class instance creation
expression, if any, in the order they appear in the expression.
Why does the anonymous constructor take arguments at all?
Since you can't create a constructor for an anonymous inner class, the instance initializer block serves that purpose (remember, you only have one instance of that anonymous inner class). The VM has no knowledge of the inner class as the compiler separates everything out as individual classes (e.g. junk.NewMain$1). The ctor for that class contains the contents of the instance initializer.
This is explayed by JLS 15.9.5.1 Anonymous Constructors:
...the anonymous constructor has one formal parameter for each actual
argument to the class instance creation expression in which C is
declared.
Your instance initializer has a reference to a Calendar object. How else is the compiler going to get that runtime value into your inner class (which is created as just a class for the VM) except through the constructor?
Finally (yay), the answer to the last burning question. Why doesn't the constructor require a String? The last bit of JLS 3.10.5 explains that:
Strings computed by constant expressions are computed at compile time
and then treated as if they were literals.
In other words, your String value is known at compile time because it's a literal so it does not need to be part of the anonymous constructor. To prove this is the case we'll test the next statement in JLS 3.10.5:
Strings computed by concatenation at run time are newly created and
therefore distinct.
Change your code thusly:
String str1 = "I'm";
String str2 = " final!";
final String finalString = str1 + str2
and you'll find your ctor is now (in the non-static context):
my ctor is junk.NewMain$1(junk.NewMain,java.lang.String,java.util.Calendar)
Phew. I hope this makes sense and was helpful. I learned a lot, that's for sure!
Because in the second case there is no default constructor anymore.
In the first case the final string gets inlined because it is a constant.
In the second case the anonymous inner class has to accept instance of Calendar into its constructor to capture the state. You can easily confirm that doing this:
Object tmp = object2.getClass().getDeclaredConstructor(Calendar.class).newInstance(calendar);
I have two classes and an interface shown below.
Quick summary: Interface Winterface, Class Big, Class Little that extends Big and implements Winterface.
public interface Winterface {}
public class Big {
public int hello = 88;
public Big() {}
public void theMethod() {
System.out.println ("Big was here: " + (this instanceof Winterface) + ", " + this.hello);
}
}
public class Little extends Big implements Winterface{
private boolean hello = true;
public Little(){}
public void theMethod() {
super.theMethod();
System.out.println("Little was here: " + hello);
}
public static void main(String [] args) {
Little l = new Little();
l.theMethod();
}
}
When I execute the main in Little, I get the following output
Big was here: true, 88
Little was here: true
my question is, how can
1) (this instanceof Winterface) return true but
2) this.hello be 88?
If this.hello = 88, then this = Big, which isn't an instance of Winterface.
I do not understand how this is possible, thanks in advance
EDIT: THANKS everyone I understand now that 'this' refers to little, which is a Big and implements Winterface. Since the method is being called as super.theMethod(), the variable 'hello' available is the one in Big even though 'this' refers to little.
this can only be one class. However this.hello is the field accessible to that class.
As this can only be one class it is a Little which has a parent Big and implements Winterface When you call a method in its parent which can only see hello that is what it sees.
i.e. Java supports polymorphism for methods but not fields.
l is Little but Little is a Big and also implements the behavior of Winterface.
The super is a call to the parent class so the hello member of the parent class (i.e. Big) is used.
You are not doing this.hello but super.theMethod() that uses the parent's class member variable hello.
UPDATE:
The super.theMethod() invokes the corresponding method in the parent class. In the parent class you access the fields of the parent (which also belong to the derived class since Little is also a Big). So the this.hello at that point is accessing the part of the code that is of the parent class.
You can imagine the memory print of Little as follows:
++++++++
+ Big +
--------
+Little+
++++++++
So Little has all the members variables of the parent i.e. Big and when the code runs inside super.theMethod() it is running inside the "code area" of Big.
As Peter states in his answer, polymorhism is not supported for methods and I hope that this overly simplistic description helps understand this
This is because the this instanceof ... check does not use the static (i.e., compile-time) type (which is Big), but the object's (this') dynamic run-time type (i.e., this.getClass()), which is Little in your example. If it would use the static type, the operator would be pretty pointless, since we would have:
Object obj = "foo";
if (obj instanceof Object) { /* always entered */ }
/* but */ if (obj instanceof String) { /* never entered */ }
statically, at compile-time. The purpose of the instanceof operator is to enable run-time type testing, for example:
Object obj = /* whatever */;
if (obj instanceof String) {
String str = (String)obj; // Cast cannot fail
...
} else if (obj instanceof Long) {
Long val = (Long)obj; // Cast cannot fail
...
}
Note, that this technique should only be used sparingly.
Your variable is an instance of Big and of Little. It's a direct instance of Little, but since Little inherits from Big the instanceof operator will return true for Big too.
Little l = new Little();
System.out.println(l instanceof Little); // true, l is an instance Little
System.out.println(l instanceof Big); // true, l is an instance of Little which inherits from Big
Your other misunderstanding (I'm assuming) is how the 'method lookup' works. When you call theMethod the it picks Little's implementation of that method. When you call super.theMethod though, you've explicitly said "call Big's version of this method", and then inside that method it's using Big's hello variable rather than Little's hello variable.
What is happening here is that when you are defining your variable hello in Little you are not overwriting the variable hello that is inside Big you are defining a new variable hello within Little that is hiding the variable hello within Big. Thus within the scope of Big, hello will refer to the integer value of 88 and within the scope of Little, hello will refer to true. These are different variables both contained within your object, the only difference is the scope by which you refer to them.
Like others here have said, instanceof is an operator that compares the runtime type of your object (what is returned by this.getClass()). When in Big even though the scope of the variables within your object will refer to Big, this is still of runtime type Little which is why it is an instance of Winterface.
Trying to understand upcasting in Java. Recently observed strange behavior.
Example:
public class A extends B {
public int i = 2;
public void printI() {
System.out.println("print i = " + this.i);
}
public static void main(String[] args) {
B a = new A(); // <- upcasting here
System.out.println("i = " + a.i);
a.printI();
}
}
class B {
public int i = 1;
public void printI() {}
}
//Output:
//i = 1
//print i = 2
Seems, that upcasted object has two separate "i" properties. One "i" accessible directly (a.i) and the other through methods of child class (a.printI()).
Looks like upcasted object gets properties from superclass and methods from child class.
How object can have two separate "i"s?!
Seems, that upcasted object has two separate "i" properties.
Firstly, it's worth being clear about terminology. There's no such thing as an "upcasted object" - and "i" is a field in each of A and B.
But yes, there are two separate fields here. It's not like one field "overrides" another or anything like that.
It's not clear what you were trying to achieve, but the declaration of i in A shadows the declaration of i in B. See section 6.4 of the Java Language Specification for more information.
Note that in almost all cases, fields should be private - at which point the hiding really doesn't matter, as you wouldn't try to refer to a variable which wasn't declared in the class you're coding in anyway.
That's how Java works. You have both fields "available", they just happen to have the same name. When you reference from the subclass, it is hiding the superclass' version, but it is still there.
Say if I have a class named Car I can use the following line of code in certain situations.
Car.class
My question is there a way I can make the same type of call if a user supplies a class name at run time. Have tried something similar to the below but no joy, is there a way i can do it.
String className = "Car";
Class.forName(className ).class;
Also I need to be able to cast dynamically, if the user specifies a list of objects I need to be able to dynamically cast.
e.g. instead of Car myCar = (Car) object
I need to be able to have to the user specify the name/type of class at run time so that I need to be able to do something along the lines of ClassName myObj = (ClassName) object.
Class.forName("Car") already returns the same as Car.class.
For casting, you can then use Class.forName("Car").cast(object), which would return a Car object. Take a look at the API, mostly the java.lang.Class part of it.
Also, since you're casting # runtime, there's no type safety, and you should check whether object extends or implements Car before doing it, otherwise you'll get an exception. A question I asked ~ a year ago and the answers there may be relevant to you as well.
Though, as others already said, this smells & you could probably redesign it in a better way, also note that this type of casting will typically be pretty slow because Java needs to examine the type hierarchy (it needs to throw a ClassCastException if it can't cast to Car).
Given the nature of the question, most of the answers to this are straight from the Reflection API documentation. I would suggest you take a look at this: http://docs.oracle.com/javase/tutorial/reflect/class/index.html. If this does not help and you need help with something specific, we can look at that.
What you are looking for is a feature called Reflection in the Java programming language.
It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
A Simple Example from http://java.sun.com
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[])
{
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
}
catch (Throwable e) {
System.err.println(e);
}
}
}
For an invocation of:
java DumpMethods java.util.Stack
the output is:
public java.lang.Object java.util.Stack.push(
java.lang.Object)
public synchronized
java.lang.Object java.util.Stack.pop()
public synchronized
java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized
int java.util.Stack.search(java.lang.Object)
Here is an example of creating objects at runtime:
import java.lang.reflect.*;
public class constructor2 {
public constructor2()
{
}
public constructor2(int a, int b)
{
System.out.println(
"a = " + a + " b = " + b);
}
public static void main(String args[])
{
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct
= cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
You can read more about it here and here - for indepth view
Also look here:
What is reflection and why is it useful?
You want to interact with myObj, so rather than going through these gymnastics, think about adding an interface that models the interactions you want to have with the objects, then use that interface in the code. The classes supplied by the user can then be validated to implement the necessary interface and errors raised appropriately.
The expression Car.class returns the java.lang.Class object for class Car.
A statement Class.forName("Car") will also return the java.lang.Class object for class Car (assuming that class Car is in the default package). Note: No need to append .class; that would give you the Class object of class Class itself, which is not what you want.
Class Class has methods to check if an object is an instance of the class that the Class instance represents (hope this is not too confusing...). Since you don't know the name of class Car at compile time, you're not going to have any kind of compile time type safety.
Lookup the API documentation of java.lang.Class.
I'm trying to make instances of anonymous classes using reflection. But ocassionally I've seen strange behaviour during instantination.
Please, look at these similar fragments of code
public class HideAndSeek {
#SuppressWarnings("unchecked")
public static void main(String[] args) throws IllegalAccessException, InstantiationException{
final String finalString = "I'm final :)";
Object object2 = new Object(){
{
System.out.println("Instance initializing block");
System.out.println(finalString);
}
private void hiddenMethod() {
System.out.println("Use reflection to find me :)");
}
};
Object tmp = object2.getClass().newInstance();
}
}
This code works well, and the output expected
Instance initializing block
I'm final :)
Instance initializing block
I'm final :)
After this I've decided to change code in simple way (just added java.util.Calendar)
import java.util.Calendar;
public class HideAndSeek {
#SuppressWarnings("unchecked")
public static void main(String[] args) throws IllegalAccessException, InstantiationException{
final String finalString = "I'm final :)";
final Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTime().toString()); //works well
Object object2 = new Object(){
{
System.out.println("Instance initializing block");
System.out.println(finalString);
//simply added this line
System.out.println(calendar.getTime().toString());
}
private void hiddenMethod() {
System.out.println("Use reflection to find me :)");
}
};
Object tmp = object2.getClass().newInstance();
}
}
And here is output that I've got:
Wed Aug 17 02:08:47 EEST 2011
Instance initializing block
I'm final :)
Wed Aug 17 02:08:47 EEST 2011
Exception in thread "main" java.lang.InstantiationException: HideAndSeek$1
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at HideAndSeek.main(HideAndSeek.java:29)
As you may see - new instance hasn't been created.
Could anybody explain me, the reason of such changes?
Thanks
This is a very simple question with a very complex answer. Please bear with me as I try to explain it.
Looking at the source code where the exception is raised in Class (I'm not sure why your stack trace doesn't give the line numbers in Class):
try
{
Class[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// removed some code that was not relevant
}
catch (NoSuchMethodException e)
{
throw new InstantiationException(getName());
}
you see that NoSuchMethodException is being rethrown as InstantiationException. This means there is not a no-arg constructor for the class type of object2.
First, what type is object2? With the code
System.out.println("object2 class: " + object2.getClass());
we see that
object2 class: class junk.NewMain$1
which is correct (I run sample code in package junk, class NewMain).
What then are the constructors of junk.NewMain$1?
Class obj2Class = object2.getClass();
try
{
Constructor[] ctors = obj2Class.getDeclaredConstructors();
for (Constructor cc : ctors)
{
System.out.println("my ctor is " + cc.toString());
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
which gives us
my ctor is junk.NewMain$1(java.util.Calendar)
So your anonymous class is looking for a Calendar to be passed in. This will then work for you:
Object newObj = ctors[0].newInstance(Calendar.getInstance());
If you have something like this:
final String finalString = "I'm final :)";
final Integer finalInteger = new Integer(30);
final Calendar calendar = Calendar.getInstance();
Object object2 = new Object()
{
{
System.out.println("Instance initializing block");
System.out.println(finalString);
System.out.println("My integer is " + finalInteger);
System.out.println(calendar.getTime().toString());
}
private void hiddenMethod()
{
System.out.println("Use reflection to find me :)");
}
};
then my call to newInstance won't work because there are not enough arguments in the ctor, because now it wants:
my ctor is junk.NewMain$1(java.lang.Integer,java.util.Calendar)
If I then instantiate that with
Object newObj = ctors[0].newInstance(new Integer(25), Calendar.getInstance());
a peek inside using the debugger shows that finalInteger is 25 and not the final value 30.
Things are slightly complicated because you're doing all of the above in a static context. If you take all your code above and move it into a non-static method like so (remember, my class is junk.NewMain):
public static void main(String[] args)
{
NewMain nm = new NewMain();
nm.doIt();
}
public void doIt()
{
final String finalString = "I'm final :)";
// etc etc
}
you'll find the ctor for your inner class is now (removing my added Integer reference):
my ctor is junk.NewMain$1(junk.NewMain, java.util.Calendar)
The Java Language Specification, section 15.9.3 explains it this way:
If C is an anonymous class, and the direct superclass of C, S, is an
inner class, then:
If the S is a local class and S occurs in a static context, then
the arguments in the argument list, if any, are the arguments to
the constructor, in the order they appear in the expression.
Otherwise, the immediately enclosing instance of i with respect to
S is the first argument to the constructor, followed by the
arguments in the argument list of the class instance creation
expression, if any, in the order they appear in the expression.
Why does the anonymous constructor take arguments at all?
Since you can't create a constructor for an anonymous inner class, the instance initializer block serves that purpose (remember, you only have one instance of that anonymous inner class). The VM has no knowledge of the inner class as the compiler separates everything out as individual classes (e.g. junk.NewMain$1). The ctor for that class contains the contents of the instance initializer.
This is explayed by JLS 15.9.5.1 Anonymous Constructors:
...the anonymous constructor has one formal parameter for each actual
argument to the class instance creation expression in which C is
declared.
Your instance initializer has a reference to a Calendar object. How else is the compiler going to get that runtime value into your inner class (which is created as just a class for the VM) except through the constructor?
Finally (yay), the answer to the last burning question. Why doesn't the constructor require a String? The last bit of JLS 3.10.5 explains that:
Strings computed by constant expressions are computed at compile time
and then treated as if they were literals.
In other words, your String value is known at compile time because it's a literal so it does not need to be part of the anonymous constructor. To prove this is the case we'll test the next statement in JLS 3.10.5:
Strings computed by concatenation at run time are newly created and
therefore distinct.
Change your code thusly:
String str1 = "I'm";
String str2 = " final!";
final String finalString = str1 + str2
and you'll find your ctor is now (in the non-static context):
my ctor is junk.NewMain$1(junk.NewMain,java.lang.String,java.util.Calendar)
Phew. I hope this makes sense and was helpful. I learned a lot, that's for sure!
Because in the second case there is no default constructor anymore.
In the first case the final string gets inlined because it is a constant.
In the second case the anonymous inner class has to accept instance of Calendar into its constructor to capture the state. You can easily confirm that doing this:
Object tmp = object2.getClass().getDeclaredConstructor(Calendar.class).newInstance(calendar);