Java generic classes - java

I understand that in the fields of a class, you can make the field type the name of another class and then in the constructor initialise that field by calling a new class of that type, i.e.
public class Auction {
private Bid bid;
}
public Auction {
bid = new Bid();
}
The main reason for doing this is, as I understand it, to access the methods of that class.
My question is I've noticed in some methods that there are local variables created that have a type of a different class with a variable name. What is the purpose of assigning a local variable name with a type of another class? Is this another way of just accessing those methods directly, even if it hasn't been done in the fields or constructor?

You can do this assignment only if type of the right part is-a type of the left part. So, for example, you can use methods of left part' type with realization from right part' type.
Number number = new Integer(10);
See also OOP in Java and Polymorphism in Java.

First of all, you need to learn some basics about OOP. We use Objects to model the problems and solve them in Object Oriented Programming.
These "type of a different class with a variable name" is an instance of a class, which is called an Object. We can assign a variable name to an object in order to use that object and its behaviors.

Related

Why can I instantiate an interface without declaring a class? [duplicate]

This question already has answers here:
Why are only final variables accessible in anonymous class?
(15 answers)
Closed 6 years ago.
So in Java it's possible to instantiate an interface without creating an explicit class
public interface Foo {
public void OnNotify()
}
Say I do the following somewhere else, say in a method Subscribe
public void Subscribe()
{
final int someInt = 5;
Foo bar = new Foo() {
final int value = someInt;
#Override
public void OnNotify()
{
Log.d("Debug", "You are being notified that I hold the value " + value);
}
}
someObject.AddSubscription(bar);
}
This is used extensively in Android for setting listeners to events.
Why is this possible, and does this kind of instantiation have a special name? Is this related to lambda functions in some way perhaps?
And why do I need to make a 'final' variable if I want to give it to this instantiated interface to hold. Say for example I wanted to pass the current iteration 'i' of a for loop to identify what index of an array a subscription references. I need to declare a final variable to hold 'i', and then pass it into the instantiated interface.
Edit:
I'm still asking why I can instantiate an interface without making a class first, and what it's called. Not knowing what this is, there's no way I could have found the duplicate question, which doesn't cover what a Java anonymous class is.
Why is this possible, and does this kind of instantiation have a special name? Is this related to lambda functions in some way perhaps?
I don't know of any "special name" for this. I generally refer to it as a "interface implementation declaration." That's just me though, and maybe that's not accurate or correct.
I believe they are not, because aside from syntax differences, I look to lambdas as a method-class like structure, and this form is overriding methods from an object type. When passing an interface object, you're passing reference of a type.
And why do I need to make a 'final' variable if I want to give it to this instantiated interface to hold.
The way I have looked at it, and understood it to be, is because this declaration inline and not in a separate class doesn't quite change what an Interface still is. In the Java programming language, an interface is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types Link
An interface is required to have a constant, and to me final is a keyword that works similarly to the C/C++ keyword const in that it isn't holding the value but a reference to the type that you've declared. These values are immutable, preventing any copies and changes, as they only contain a reference to the location of the value.
So, overall, I believe that an interface declaration like how you illustrate is not working as declaring an instance of the actual interface class, but rather it's creating an object of that type and that object is a new location in memory that holds references to these methods and members (like a class).
Hope this helps some. I don't normally like to volunteer answers to something I am not 100% sure on, and wish this was a comment more (but lack the rep still for that), but hopefully it helps clear some things.
You can read the Java Language Specification here for more information on Interfaces too. Hope that helps.

Why do we need Downcasting really? [duplicate]

This question already has answers here:
Upcasting and Downcasting in java
(8 answers)
Closed 9 years ago.
I am trying to figure out why do I need Downcasting. I reread my notes from collage and found the below example.
class Student {...}
class Graduate exteds Student {
getResearchTopic(){...} // this method only exists in Graduate class.
}
We have a ref to Student class and want to access to getResearchTopic method;
Student s1 = new Graduate();
if(s1 instanceof Graduate){
((Graduate)s1).getResearchTopic();
}
Great example for Downcasting hah? My question is Why not declare s1 as a Graduate in the first place? Is there a real life example where I will have to downcast instead of using an instance of actual class?
Well, you could have declared the reference s1 to be of type Graduate. The main benefit you get by declaring the reference of super type, is the power of polymorphism.
With a super type reference, pointing to a sub class object, you can bind the same reference to multiple sub class objects. And the actual method invoked will be decided at runtime, based on what object is being pointed to. But, the main condition for this is, that method should also be defined in the subclass, else the compiler will fail to find the method declaration.
Here, you were forced to downcast, because you haven't defined the method in the super class. As compiler cannot see the definition of that method in Student class. It has no idea about what the actual object s1 points to. Remember, compiler only checks the reference type to find the meethod declaration.
In general, whenever you see yourself downcasting to a subclass in your code, it is almost always a sign a something wrong (there are some exceptions though). And you should modify your classes.
Let's see what benefit you get by using a super class reference instead of a subclass reference:
For e.g: Suppose you have another sub class of Student as:
class Phd extends Student {
getResearchTopic(){...}
}
and you also provide a definition (a default one) in Student class:
class Student {
getResearchTopic(){...}
}
Now, you create a following two objects, both being pointed to by Student reference:
Student student = new Phd();
student.getResearchTopic(); // Calls Phd class method
student = new Graduate();
student.getResearchTopic(); // Calls Graduate class method
So, with only a single reference, you get to access methods specific to subclasses.
One major implementation of this feature you can see in factory method pattern, where a single static method returns an object of different sub classes based on some condition:
public static Student getInstance(String type) {
if (type.equals("graduate"))
return new Graduate();
else if (type.equals("phd"))
return new Phd();
}
So, you can see that the same method returns an object of different subclasses.
All of the above stuffs you can do just because of one concept:
A Super class reference can refer to any sub class objects, but not vice-versa.
Say you have a method that takes a Student as a parameter. Most of the things it does are generic for all students. But if it is a Graduate there might be something else it does as well. In that case you would need to determine if the Student passed in was actually a Graduate and do some special logic in that instance.
Maybe something like this:
class StudentDAO {
public void SaveStudent(Student s) {
// Do something to save the student data to a database.
if ( s instanceof Graduate ) {
// Save their research topic too.
}
}
}
Note that doing that kind of thing is usually a poor programming practice, but sometimes it makes sense.
When you deserialize an object using the default Java deserializer, you use this code (and you use analogous code when using another deserializer, e.g. the Jackson JSON deserializer)
ObjectInputStream ois = new ObjectInputStream(in);
Object obj = ois.readObject();
You then need to cast obj to its actual type, because readObject() will always return a plain old Object - the method can't statically verify what sort of object is being read
In cases where you want to use polymorphism, it would be nice to work with Student objects, and then "downcast" to use methods specific to Graduate objects.
In general, if you have a method that works with Student objects, that method don't really know at compile-time what specific type of Student objects are passed in. Thus, at run-time, the method should check for the specific type and process accordingly.
Downcasting does help when you're trying to make generic methods. For example, I often see code that parses an XML String into an Object. The Object can then be downcast into the specific Object that you (as the coder) know it represents.
private static XStream xstream = new XStream(new DomDriver());
static {
xstream.processAnnotations(MyFirstClass.class);
xstream.processAnnotations(MySecondClass.class);
// ...
}
public static Object fromXML(String xml) {
return xstream.fromXML(xml);
}
This lets me make a very generic method which does what I want it to do in all cases. Then, when I call it, I can simply downcast the Object into what I know it's going to be. It prevents me from having to make a separate parse method for every object type and improves the readability of my code.
MyFirstClass parsedObject = (MyFirstClass) MyXMLTransformer.fromXML(xml);

Java object construction

I am new to Java and I'd like to figure out why some code is written in one way instead of another. When you construct an object in Java, the syntax is something like
class variable = new class(parameters);
or
class variable;
variable = new class(parameters);
I wonder why the class name has to be invoked twice. As documented on Wikipedia, Python (which I don't know either) follows what according to me is a more intuitive approach, i.e.
variable = class(parameters)
Is it because Java can handle other possibilities?, e.g.
class1 variable = ... class2(parameters)
Thanks in advance.
Because the left hand side can be a reference type and the right hand side it can be any assignable object type.
This assigns the reference variable variable of type class1 an object of class1.
class1 variable = new class1(parameters);
This assigns the reference variable variable of type class1 an object of subclass1, where subclass1 can be a subclass of class1 or an implementation of class1 interface.
class1 variable = new subclass1(parameters);
Python uses Dynamic Typing (Duck Typing) and hence you need not declare a variable.Dynamic typed languages are those in which variable type checking is done at run-time.
Static typed programming languages are those in which variables need not be defined before they’re used. This implies that static typing has to do with the explicit declaration (or initialization) of variables before they’re employed. Java is an example of a static typed language. Statically typed languages that lack type inference (such as C and Java) require that programmers declare the types they intend a method or function to use. This can serve as additional documentation for the program, which the compiler will not permit the programmer to ignore or permit to drift out of synchronization.Static typed languages are those in which variable type checking is done at compile-time.
Python (which I don't know either) follows what according to me is a more intuitive approach
The concern with dynamic typing, like this is :
variable = class(parameters);
In future if by mistake you misspelled the variable name variable with varaible , it would not be caught at compile time , but you can get erroneous output or exception at runtime. With static typing , Java detects such flaws at compile time itself.
Because they mean different things - and don't need to be the same.
The class descriptor on the left defines the type of the variable. This constrains what can be assigned to that variable, and also provides some guarantees to callers about what the objects there can do.
The class name when it appears on the right is actually the "method name" of a constructor. You're calling a method which creates a new object. The object you create can be anything, so long as it's assignable to the type of the variable.
So for example, you can do this:
Object foo = new String("bar");
or this:
Collection x = new ArrayList();
(though in practice you'd probably want to use generic parameters on that last one - I've left them out here so as not to confuse the question of classes.)
Java is a static typed programming language. However, Python is a dynamic typed programming language.
Wikipedia has very good explanation here.
Class name has to be invoked twice because you have to specify the type of the instance.
You can also do things like this when creating new instance:
public class Test extends Test1 {}
...
Test1 test = new Test(parameters);
Doing things like this will determine which class' variables and methods you can actually access while maintaining stuffs such as class fields.
SomeClass variable;
variable = new SomeClass(params);
The first line declares a variable and states that it is of type SomeClass. At this point the variable is empty and doesn't reference anything.
The second line creates a new object of type SomeClass and stores a reference to it in variable.
Writing both things in one line like this:
SomeClass variable = new SomeClass(params);
can be done to make things shorter. But at the end there is always a variable declaration and an object construction. Variables must always be of some type, you can't declare a variable without type (Java is strongly typed).
The left hand side (reference definition type) is a reference to an object or instance that can be the type of that class or any subclass of that reference type. Also, in accord with the following reference Python is a dynamic type programming language where every variable name (unless it's null) is bound to only an object. Java, on the other hand, is a statically-typed programming language.

Java reflecting nested anonymous classes

Why does this code return "class java.lang.Object" ?
Object a = new Object() {
public Object b = new Object(){
public int c;
};
};
System.out.println(a.getClass().getField("b").getType());
Why does the inner-inner type get lost? How can I reflect the c field ?
Edit:
This one works (as pointed out in some answers):
a.getClass().getField("b").get(a) ...
But then I have to invoke a getter, is there any way to reflect c with only reflection meta data?
Because b is declared as Object:
public Object b = ...;
There is a distinction between type of variable (static type) and type of the object referenced by that variable (runtime type).
Field.getType() returns static type of the field.
If you want to get runtime type of the object referenced by the field, you need to access that object and call getClass() on it (since a is declared as Object and therefore b is not visible as its member you have to use reflection to access it):
System.out.println(
a.getClass().getField("b").get(a).getClass());
UPDATE: You can't reflect c without accessing the instance of object containing it. That's why these types are called anonymous - a type containing c has no name, so that you can't declare field b as a field of that type.
Let's look at this line carefully:
System.out.println(a.getClass().getField("b").getType());
First, your take the a variable. It is of some anonymous subclass of the Object. Let's call that class MyClass$1. Okay, so far so good.
Next, you call the getClass() method. It returns the class of a, that is, a description of the MyClass$1 class. This description is not tied to any particular instance of that class, though. The class is the same for all instances, be it a or whatever else (unless different class loaders are used). In this particular case, however, there can be only one instance, because the class is anonymous, but the mechanism is still the same.
Now, from the class, you get the field b. As the class isn't directly tied to any of this instances, the field has nothing to do with a either. It's just a description of what exactly the field a of the class MyClass$1 is.
Now you get its type. But since it isn't tied to any instance, it can't know the runtime type. In fact, if the class wasn't anonymous, you could have numerous instances of MyClass$1, each having different value in a. Or you could have no instances at all. So the only thing getType() can possibly tell you is the declared type of b, which exactly what it does. The b field could in fact be null at that point, and you'd still get Object as the result.
The Field class provides the get() method to actually access that particular field of some object, like this:
System.out.println(a.getClass().getField("b").get(a).getClass());
Now you get something like MyClass$1$1, which is the name of the anonymous class of the object that field b references to, in the a instance.
Why does the inner-inner type get lost?
Because you are getting the type type of the field "b" (Object), not the type of the anonymous inner class of which you assigned the instance to "b".
How can I reflect the c field ?
You could use this
System.out.println(a.getClass().getField("b").get(a).getClass().getField("c"));
instead. This gets the value of the field "b" and it's class, but this only works if "b" is guaranteed be not null.
Doing this seems to indicate a bad design, there might be other ways to archive what you want to do with this. But without knowing the purpose, this is everything I can answer.

Uninstantiated Anonymous Classes in Java

It's been about 6 years since I've written Java, so please excuse the rust.
I'm working with a library method that requires that I pass it Class objects. Since I'll have to invoke this method a dynamic number of times, each time with a slightly different Class argument, I wanted to pass it an anonymous class.
However, all the documentation/tutorials I've been able to find so far only talk about instantiating anonymous classes, e.g.:
new className(optional argument list){classBody}
new interfaceName(){classBody}
Can I define an anonymous class without instantiating it? Or, perhaps more clearly, can I create a Class object for an anonymous class?
Unfortunately, there's no way you can dodge the instantiation here. You can make it a no-op, however:
foo((new Object() { ... }).getClass());
Of course, this might not be an option if you have to derive from some class that performs some actions in constructor.
EDIT
Your question also says that you want to call foo "each time with a slightly different Class argument". The above won't do it, because there will still be a single anonymous inner class definition, even if you put the new-expression in a loop. So it's not really going to buy you anything compared to named class definition. In particular, if you're trying to do it to capture values of some local variables, the new instance of your anonymous class that foo will create using the Class object passed to it will not have them captured.
short answer
you cannot (using only JDK classes)
long answer
give it a try:
public interface Constant {
int value();
}
public static Class<? extends Constant> classBuilder(final int value) {
return new Constant() {
#Override
public int value() {
return value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}.getClass();
}
let's creating two new class "parametric" classes:
Class<? extends Constant> oneClass = createConstantClass(1);
Class<? extends Constant> twoClass = createConstantClass(2);
however you cannot instantiate this classes:
Constant one = oneClass.newInstance(); // <--- throws InstantiationException
Constant two = twoClass.newInstance(); // <--- ditto
it will fail at runtime since there is only one instance for every anonymous class.
However you can build dynamic classes at runtime using bytecode manipulation libraries such ASM. Another approach is using dynamic proxies, but this approach as the drawback that you can proxy only interface methods (so you need a Java interface).
You can only reference an anonymous class ONCE. If you do not instantiate it there, you cannot instantiate it since you do not have a name for it.
Hence I believe that anonymous classes can only be used in conjunction with a "new BaseClass()".
In your situation you would pass a BaseClass object to your method doing the work, and instantiate the anonymous object in the source code when you need the object to pass.
You can't access the Class object of an anonymous class without instatiating it. However, if you only need access to the class, you could define local classes within your method and refer to these using the ClassName.class literal syntax.
You can assume the name of an anonymous class and call Class.forName("mypackage.MyBaseClass$1") to get a handle to an anonymous class. This will give you the first anonymous class defined in your MyBaseClass, so this is a rather fragile way to refer to a class.
I suspect whatever you are trying to do could be done a better way. What are you really trying to achieve? Perhaps we can suggest a way which doesn't require you to pass a Class this way.
You can access the class object of an anonymous class by calling .getClass() on it immediately after creation. But what good would that do?
I think the key is in this part of what you said:
I'm working with a library method that requires that I pass it Class
objects.
Why does it want you to pass it Class objects? What does this library do with the Class objects you pass it? Instantiate objects? But if so, what constructor does it use and how does it decide what arguments to pass? I don't know what library you are using or what it does, but I would guess that it always creates objects using the no-argument constructor. However, that will not work for anonymous classes anyway, since they have no public constructor (and in any case, to instantiate any non-static inner class, a reference to the outer instance must be provided, so there is no no-argument constructor).

Categories

Resources