If I'm only given a field instance from a class, without further knowledge about the class that declares that field, is it possible to get an instance of the declaring (outer) class?
For instance, consider the following class structure.
class A {
static final Tclass t = Tclass.create();
}
Now, in some other function, we are only given t (Tclass instance). Is it possible to use reflection in some way to grab the outer/declaring class (class A) that holds t?
I don't think the statement given t means what you think it means.
If you mean you do something like
someMethod(t);
and you want someMethod to get a reference back to A, you're out of luck. When used in an expression like that, the expression t resolves to a value. That value is a reference to an object. Such a reference is one-way only. someMethod has absolutely no knowledge about the existence of a static variable t.
If you mean you have a Field instance for t, you can simply call Field#getDeclaringClass() to get the declaring class.
Related
I'm trying to load a serialized object within the class using a method like this one:
private void loadCatalog(MyClass myClassNew)
{
this = myClassNew;
}
So I have this method in my MyClass, and I receive as a parameter an object having the type of MyClass. How can I do something like above? The code above gives me an error of which I'm not sure why. The object myClassNew is the same as the one before serializing, so I'm sure that I receive a valid object of type MyClass.
There is no way to do that. You must write code that copies each instance field of MyClass from the argument to this. For instance:
this.firstName = myClassNew.firstName;
this.lastName = myClassNew.lastName;
You could use reflection do to this, but you probably shouldn’t. Unless MyClass is very simple, you may find that some fields require special handling. For example, copying a List reference would be very bad, unless it’s an unmodifable List, as the two objects should share a reference to the same List object.
You will get an error:
The left-hand side of an assignment must be a variable
"this" is not a variable that you can assign to. you can create fields in the object and do "this.field1 = myClassNew", but you cannot assign to "this".
I know how in Java, a class is referenced like com.google.googlemaps.exampleClass.exampleMethod().
Is it possible to interchange the first parts of the referenece (in this case, the com.google.googlemaps) using a variable (Class c)?
EDIT
Ok, after some confusion, I'm going to (try to) provide an example
We have Class A. I can add a new instance of it. Each instance has the variables name (a String), and redir (currently in turmoil). redir is the variable which is supposed to hold the reference for the class, so I can call a specific method from those classes, so redir is like com.google.googlemaps etc.
Like c.exampleMethod()?
Yes, like so
import com.google.googlemaps.ExampleClass;
...
ExampleClass c = new ExampleClass();
c.exampleMethod();
from your example:
com.google.googlemaps.exampleClass.exampleMethod()
the exampleMethod() is a static method.
If you have an object/reference with Type Class<com.google.googlemaps.exampleClass> (Class c) you can call getMethod to get the Method object. And then you could call invoke method to invoke the method.
I don't really understand how the class keywords work in some instances.
For example, the get(ClientResponse.class) method takes the ClientResponse.class. How does it use this when it gets it, and what are the advantages over just passing an instance of it?
SomeClass.class
returns a Java Class object. Class is genericized, so the actual type of SomeClass.class will be Class<SomeType> .
There are lots of uses for this object, and you can read the Javadoc for it here: http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html
In ClientResponse.class, class is not a keyword, neither a static field in the class ClientResponse.
The keyword is the one that we use to define a class in Java. e.g.
public class MyClass { } /* class used here is one of the keywords in Java */
The class in ClientResponse.class is a short-cut to the instance of Class<T> that represents the class ClientResponse.
There is another way to get to that instance for which you need an instance of ClientResponse. e.g
ClientResponse obj = new ClientResponse();
Class clazz = obj.getClass();
what are the advantage over just passing a instance of it?
In the above example you can see what would happen in case obj was null (an NPE). Then there would be no way for the method to get the reference to the Class instance for ClientResponse.
The Class class, which is different from the class keyword, is meta-data describing instances. It tells you about the methods, data members, constructors, and other features of the instances that you create by calling new.
For example get(ClientResponse.class) method takes the
ClientResponse.class how does it uses this when it gets it and what
are the advantage over just passing a instance of it?
You can't pass an instance of ClientResponse to this method; it's expecting meta-data about all instances of ClientResponse. If you passed an instance, you'd expect that the method might change the state of that instance. But passing the meta-data about all instances might allow the method to create a new kind of instance (e.g. a dynamic proxy) or do something else that depends on the meta-data about all instances of ClientResponse. See the difference?
A class is a "blueprint" of the object. The instance is a object.
If we have
public class SomeClass {
int a;
SomeClass(int a) {
this.a = a
}
}
We can have an instance of this class
SomeClass c = new SomeClass(10);
c is an instance of the class. It has a integer a with value 10.
The object SomeClass.class represents a Class.
Here SomeClass.class is a object of the type Class which has the information that SomeClass is
a concrete class with
one constructor
with a integer member variable
and lots more other metadata about the class SomeClass. Note that it does not have a value for a.
You should use get(c) incase you are planning to do something with a instance of c like call c.a or other useful functions to manupulate/get data of the instance.
You should use get(SomeClass.class) when the get returns something based on the fact that the argument is some type of class. For example, if this is a method on a Registry class which has a map which retrieves a implementation class based on type of class passed in.
The very most important fact is - you don't need to have an instance to call the method. It's critically useful in situations when you cannot for some reason instantiate a class, e.g. it's abstract, or have only private constructor, or can only be correctly instantiated by some framework, like Spring or JSF.
You can then call get to obtain an object of a requested type without even knowing where it does come from and how it get's created.
Here ClientResponse.class is an instance of Class<ClientResponse>. In general Class object represents type of an object. When you create new instance:
Object obj = new ClientResponse()
you can retrieve the class (type) of that object by calling:
obj.getClass()
So, why would you pass Class objects around? It's less common, but one reason is to allow some method create arbitrary number of instances of a given class:
ClientResponse resp = ClientResponse.newInstance();
There's a lot of ways Class objects can be used. This is used for Reflection. Below is a link that can help you understand more.
http://docs.oracle.com/javase/tutorial/reflect/class/classNew.html
Whenever we compile any Java file, the compiler will embed a public, static, final field named class, of the type java.lang.Class, in the emitted byte code. Since this field is public and static, we can access it using dotted notation along with class name as in your case it is ClientResponse.class.
In C++, you can use an initializer list to initialize the class's fields before the constructor begins running. For example:
Foo::Foo(string s, double d, int n) : name(s), weight(d), age(n) {
// Empty; already handled!
}
I am curious why Java does not have a similar feature. According to Core Java: Volume 1:
C++ uses this special syntax to call field constructors. In Java, there is no need for it because objects have no subobjects, only pointers to other objects.
Here are my questions:
What do they mean by "because objects have no subobjects?" I don't understand what a subobject is (I tried looking it up); do they mean an instantiation of a subclass which extends a superclass?
As for why Java does not have initializer lists like C++, I would assume that the reason is because all fields are already initialized by default in Java and also because Java uses the super keyword to call the super(or base in C++ lingo)-class constructor. Is this correct?
In C++, initializer lists are necessary because of a few language features that are either not present in Java or work differently in Java:
const: In C++, you can define a fields that are marked const that cannot be assigned to and must be initialized in the initializer list. Java does have final fields, but you can assign to final fields in the body of a constructor. In C++, assigning to a const field in the constructor is illegal.
References: In C++, references (as opposed to pointers) must be initialized to bind to some object. It is illegal to create a reference without an initializer. In C++, the way that you specify this is with the initializer list, since if you were to refer to the reference in the body of the constructor without first initializing it you would be using an uninitialized reference. In Java, object references behave like C++ pointers and can be assigned to after created. They just default to null otherwise.
Direct subobjects. In C++, an object can contain object directly as fields, whereas in Java objects can only hold references to those objects. That is, in C++, if you declare an object that has a string as a member, the storage space for that string is built directly into the space for the object itself, while in Java you just get space for a reference to some other String object stored elsewhere. Consequently, C++ needs to provide a way for you to give those subobjects initial values, since otherwise they'd just stay uninitialized. By default it uses the default constructor for those types, but if you want to use a different constructor or no default constructor is available the initializer list gives you a way to bypass this. In Java, you don't need to worry about this because the references will default to null, and you can then assign them to refer to the objects you actually want them to refer to. If you want to use a non-default constructor, then you don't need any special syntax for it; just set the reference to a new object initialized via the appropriate constructor.
In the few cases where Java might want initializer lists (for example, to call superclass constructors or give default values to its fields), this is handled through two other language features: the super keyword to invoke superclass constructors, and the fact that Java objects can give their fields default values at the point at which they're declared. Since C++ has multiple inheritance, just having a single super keyword wouldn't unambiguously refer to a single base class, and prior to C++11 C++ didn't support default initializers in a class and had to rely on initializer lists.
C++
There is a difference between
ClassType t(initialization arguments);
and
ClassType * pt;
The latter doesn't need to be initialized (set to NULL). The former does. Think of it as an integer. You can't have an int without a value, BUT you can have an int pointer without a value.
So when you have:
class ClassType
{
OtherClass value;
OtherClass * reference;
};
Then the declaration:
ClassType object;
automatically creates an instance of OtherClass in value. Therefore, if OtherClass has initialization, it must be done in the ClassType constructor. However, reference is just a pointer (address in memory) and can remain uninitialized. If you want an instance of OtherClass you must use
object.reference = new OtherClass(initialization arguments);
Java
There is only
class ClassType
{
OtherClass reference;
}
This is equivalent to a pointer in C++. In this case when you do:
ClassType object = new ClassType();
You don't automatically create an instance of OtherClass. Therefore, you don't have to initialize anything in the constructor unless you want to. When you want an object of OtherClass you can use
object.reference = new OtherClass();
Because Java does not need them to allow initialization of fields whose type has no zero-value.
In C++
class C {
D d;
}
without a member initializer for d, D::D() will be called which makes it impossible to initialize the field if there is no zero-type for D. This can happen when D::D() is explicitly declared private.
In Java, there is a known zero-value for all reference types, null, so a field can always be initialized.
Java also does a bunch of work to make sure* that all final fields are initialized before first use and before the constructor ends, so while Java has a requirement like C++'s const field initialization requirement, it just overloads this.fieldName = <expression> in the constructor body to mean field initialization.
: modulo exceptions thrown in the ctor, overridden method calls from the base class, etc.
I'm beginning to program in Java.
public static void main(String[]args)
A book said that I should use static in this case, but doesn't clearly say why I should or what it means.
Could you clarify this?
The concept of static has to do with whether something is part of a class or an object (instance).
In the case of the main method which is declared as static, it says that the main method is an class method -- a method that is part of a class, not part of an object. This means that another class could call a class method of another class, by referring to the ClassName.method. For example, invoking the run method of MyClass would be accomplished by:
MyClass.main(new String[]{"parameter1", "parameter2"});
On the other hand, a method or field without the static modifier means that it is part of an object (or also called "instance") and not a part of a class. It is referred to by the name of the specific object to which the method or field belongs to, rather than the class name:
MyClass c1 = new MyClass();
c1.getInfo() // "getInfo" is an instance method of the object "c1"
As each instance could have different values, the values of a method or field with the same name in different objects don't necessarily have to be the same:
MyClass c1 = getAnotherInstance();
MyClass c2 = getAnotherInstance();
c1.value // The field "value" for "c1" contains 10.
c2.value // The field "value" for "c2" contains 12.
// Because "c1" and "c2" are different instances, and
// "value" is an instance field, they can contain different
// values.
Combining the two concepts of instance and class variables. Let's say we declare a new class which contains both instance and class variables and methods:
class AnotherClass {
private int instanceVariable;
private static int classVariable = 42;
public int getInstanceVariable() {
return instanceVariable;
}
public static int getClassVariable() {
return classVariable;
}
public AnotherClass(int i) {
instanceVariable = i;
}
}
The above class has an instance variable instanceVariable, and a class variable classVariable which is declared with a static modifier. Similarly, there is a instance and class method to retrieve the values.
The constructor for the instance takes a value to assign to the instance variable as the argument. The class variable is initialized to be 42 and never changed.
Let's actually use the above class and see what happens:
AnotherClass ac1 = new AnotherClass(10);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
Notice the different ways the class and instance methods are called. The way they refer to the class by the name AnotherClass, or the instance by the name ac1. Let's go further and see the behavioral differences of the methods:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
AnotherClass.getClassVariable(); // Returns "42"
As can be seen, an instance variable is one that is held by an object (or "instance"), therefore unique to that particular instance, which in this example is the objects referred to by ac1 and ac2.
A class variable on the other hand is only unique to that entire class. To get this point across even better, let's add a new method to the AnotherClass:
public int getClassVariableFromInstance() {
return classVariable;
}
Then, run the following:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
ac1.getClassVariableFromInstance(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
ac2.getClassVariableFromInstance(); // Returns "42"
Although getClassVariableFromInstance is an instance method, as can be seen by being invoked by referring to the instances ac1 and ac2, they both return the same value, 42. This is because in both instance methods, they refer to the class method classVariable which is unique to the class, not to the instance -- there is only a single copy of classVariable for the class AnotherClass.
I hope that some what clarifies what the static modifier is used for.
The Java Tutorials from Sun has a section called Understanding Instance and Class Members, which also goes into the two types of variables and methods.
Please see a nice description on Wikipedia
For example, notice how in the Math class, you can say things like
Math.Abs(x);
without having to say
Math m = new Math();
These are static methods since you don't need an instance. Instance methods are those methods that require you to have an instance of a class.
Employee e = new Employee();
e.Terminate();
A static method is one that applies to the class a whole, not any particular member. .goExtinct() would be a method of the Duck population as a whole, not any particular duck. main is public and static because is has to always be available, and its not part of any particular class.
Usually, you have to have an object, an instance of a class, in order to call methods on it, for at least two reasons:
It depends on the object which class implements the method that is being called. For example if you have an instance of a subclass, the method in the subclass will be called instead, even though the code that calls the method is the same.
Objects usually have internal state (fields), that methods can refer to. This does not work if there is no object instance.
You create object instances by calling the class' constructor:
MyObject a = new MyObject();
Static methods are methods that are not attached to object instances. They can be called by just naming the class. As a result of this they
cannot be dynamically dispatched to subclasses (which is why you get a warning when you try to call it on object instances, that is just confusing syntax)
they cannot refer to instance state (non-static fields and other non-static methods).
Many people consider static methods a bad design pattern, and advise to not use them (except for public static void main) Look up the singleton instance pattern for an alternative.
In this particular case the main method must be static, because of the way the JVM will start loading classes and creating objects. When you start a Java program the JVM will look for the definition of the class that was passed to it and load it. So java MyClass will result in loading the definition of the MyClass class.
By definition a Java program will start executing in the main() method of the class that was passed to the JVM as the class to load initially. At this point in time no instance (object) of type MyClass has been created, so the main method has to be static to allow the start of the execution of your program.
If you want to see which classes are being loaded during the execution of a Java program you can use the -verbose:class command line option.
In any object oriented programming language like Java or C++ you create classes which at the very basic level are like BluePrints of a building. You can look at a blueprint and determine how various components are connected but you cannot actually live in it. It's the same with classes and object. Classes are blueprint and you create an instance of a class which is called an Object. For the same blueprint you can have multiple buildings , same way for one class you can have multiple objects. An Object is an instance of a class. Each method in a class can be called on an Object or an instance of a class, whereas for calling static methods you actually don't need an instance, you can directly call ClassName.method() without actually creating an instance of a class.
There will be times when you will want to define a class member that will be used independently of any object of that class. Normally a class member must be accessed only in conjunction with an object of its class. However, it is possible to create a member that can be used by itself, without reference to a specific instance. To create such a member, precede its declaration with the keyword static. When a member is declared static, it can be accessed before any objects of its class are created, and without reference to any object. You can declare both methods and variables to be static. The most common example of a static member is main( ). main( ) is declared as static
because it must be called before any objects exist.
The two types of static members are static fields and static methods:
Static field:
A field that’s declared with the static keyword, like this:
private static int ballCount:
The position of the static keyword is interchangeable with the positions of the visibility keywords (private and public, as well as protected). As a result, the following statement works, too:
static private int ballCount;
As a convention, most programmers tend to put the visibility keyword first.
The value of a static field is the same across all instances of the class. In other words, if a class has a static field named CompanyName, all objects created from the class will have the same value for CompanyName.
Static fields are created and initialized when the class is first loaded. That happens when a static member of the class is referred to or when an instance of the class is created, whichever comes first.
Static method:
A method declared with the static keyword. Like static fields, static methods are associated with the class itself, not with any particular object created from the class. As a result, you don’t have to create an object from a class before you can use static methods defined by the class.
The best-known static method is main, which is called by the Java runtime to start an application. The main method must be static, which means that applications run in a static context by default.
One of the basic rules of working with static methods is that you can’t access a nonstatic method or field from a static method because the static method doesn’t have an instance of the class to use to reference instance methods or fields.