I just started to learn java and i found out that, to call a method of normal class we need object but for static class we do not need any object to call we can use class reference to do that. But while coding I came across some code which really confused me. The code is.
public class MyInterceptor extends AbstractInterceptor {
#Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
String result = actionInvocation.invoke();
Here my doubt is in the 3rd line we have a reference actionInvocation for a class ActionInvocation and we have not used any new keyword and now check the 4th line we used actionInvocation to access the methos invoke(). How is this possible without using new keyword? I also checked that ActionInvocation is abstract interface.
The new keyword is only used to construct an object. Once it has been created, it can be passed around between methods, other classes, and other places where an object may be stored or transmitted.
You are making a method of MyInterceptor that accepts an ActionInvocation object. This object can either be passed as null, or would have been created elsewhere. You can perform a not-null check (via actionInvocation!=null) to ensure that you're indeed passed an object.
Also, you should remember that you yourself can create objects without using new in your class. There are such ways called factories, where you call a static method such as ByteBuffer.allocateDirect( and that internally uses the new keyword to create an instance of ByteBuffer.
That's perfectly fine code. The ActionInvocation instance is created elsewhere and passed to the intercept(...) method. In fact ActionInvocation actionInvocation is just a reference to an object of a class that extends or implements ActionInvocation, i.e. the actual class of that object could be a subclass/implementation of ActionInvocation.
The concept behind this is called polymorphism: an object of a certain class is also an object of its superclasses and/or might be referenced through implemented interfaces.
An example:
Suppose you have an object like this:
Integer someInt = new Integer(1);
You could pass someInt as a parameter to the following methods:
void doSomething( Integer i) { ... }
void doSomething( Number n) { ... }} //because Integer extends Number
void doSomething( Object o) { ... } //because all objects extend Object
void doSomething( Comparable c) { ...} //because Integer implements Comparable (note that I left out generics here for simplicity)
Note that you could also pass null as an object, as the others already stated, but in your case you should be safe to assume that actionInvocation is never null (this is most likely documented in the API docs).
actionInvocation is initialized(with new) in another place of the program.
You will need a little more understanding of how inheritance and interfaces work to understand this. But the overall logic here is that the method is assuming that object of type ActionInvocation is already instantiated, which might not be the case. Anyways you can look at the calling code for method intercept where an object being passed here must have been instantiated by using new.
By the way ActionInvocation is interface so any "subclass" of this interface can call this method. Have a look at the inheritance terminology to understand what that means.
public String intercept(ActionInvocation actionInvocation)
To call this method any where in your program,
you need to have a created object of type ActionInvocation, then and then only you can call that method.
Once you pass to that,The story inside is usual.
In short,
That object created before calling this method and coming here to do the stuff.
Related
I think this should be possible but I have a scenario where I'm executing a method which returns an object.
authentication.getUserAuthentication().getPrincipal()
ref
This returns an object which at runtime is cast to my custom object, however if I want to play around with the principal, I need to cast this. I want to approach this in a generic way and extra the id from this object. I want to simply be able to call
principle.getId();
As the principle object will be a custom object of mine I can ensure that this method is always there. How can I call this in a generic way that will allow future objects to this as long as they contain the method I am calling
You could use an interface, which essentially defines a set of functionalities that a class which implements that specific interface must obey to.
This is basically done by declaraing what you want to be able to call on your custom objects, eg:
interface Idable
{
public int getId();
}
Now you can state that your custom object implements that interface, and the compile will force you to override the method, or declare the class as abstract:
class CustomObject implements Idable
{
public int getId() {
return whatever;
}
}
Now you don't need to know anything more about your custom object, knowing that implements the interface is enough:
Idable idable = (Idable)authentication.getUserAuthentication().getPrincipal();
idable.getId();
Of course this requires you to be able to interact which the returned object, otherwise you will be forced to use reflection and lose type safety:
Object obj = authentication.getUserAuthentication().getPrincipal();
try {
obj.getClass().getMethod("getId").invoke(obj);
}
Unfortunately, you can't. The return type is not Object though, it's a instance of org.springframework.security.core.Authentication.
Sut since that interface does not declare a getID() method, you have to continue to cast the return value to your own type.
I'm very new to Java. This is probably a stupid question--but i can't find the answer anywhere. If you wanted to declare a method that would take in an unknown object and do something with it (copy it, for example), what would be the difference between something like:
<T> T func(Class<T> cls){
//do something
}
Object func(Object o){
//do something
}
Are they comparable? Is there anything you could/would do with one of the above methods and not the other? And where does Class<?> fit in?
The difference in your code is that former func receives a Class<T> (which can be Class<?>) which means the method only receives a Class type . The latter receives any object, regardless if it's a class or another kind of object.
From Class javadoc:
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions.
Note that Class is metadata for your classes.
If your code were like this:
<T> T func(T o){
//do something
}
Object func(Object o){
//do something
}
The main difference is the return type: the former return type should be as the same type of the argument, while the latter is a generic Object. For example:
Object func(Object o){
//do something
return o.toString(); //compiles and works
}
<T> T func(T o){
//do something
return o.toString(); //does not compile
}
Class is a very specialized type of an object. Class<T> is not a replacement for any kind of object, it is rather a class descriptor. In Java, where everything is an object, also classes are objects, so there is this type - Class - which abstracts over the "class" class of objects.
Here's an example:
If you have this:
Class<Object> obj = Object.class;
func(obj);
, this doesn't mean that inside your func method you will have access to an Object instance; you will have access to a Class<Object> instance, which is he descriptor of the Object class.
So, to answer your question, you should use Object for your declared purpose.
Class and Object are 2 different things in Java. If you wanted to take any type of object, which you don't care the type of, the following is more normally seen.
Object func(Object o){
//do something
}
It is more common to declare functions with Object vs Class, since there are a few more steps for passing a class than an object.
lets hava a look at your functions
<T> T func(Class<T> cls){
//do something
}
this one takes class as parameter, and returns instance of the class,
imagine method as black box which do some magic stuff
you enter String.class and you will get "hello world"
second one
Object func(Object o){
//do something
}
takes object as parameter and returns object, so in theory, you can insert class and returns instance, but you can also put date and received String
The first function accepts a java.lang.Class (that is also an instance of an Object class, because Class extends it. You can find more information about the Class class in the javadoc: http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html ).
Hence the first method can do something with an instance of Class and it does not accept all objects (note the capital letter, it is a name of a class).
The second method accepts all objects (because every object extends java.lang.Object). (Object's javadoc: http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html)
So if you want to create a method that may "take in an unknown object and do something with it" you have to use the second method. You should also know that usually you do not need a method that accepts any object or unknown object and you should not create such methods if you can find another solution (because it causes the code to be harder to read).
A method that accepts Class as an argument is useful when you want to do something with the definition of a class (retrieve a list of fields, methods, constructors etc.). This webpage explains how you can use the Class class: http://docs.oracle.com/javase/tutorial/reflect/index.html
Additionally, if you want to learn more about generics you should read this tutorial: http://docs.oracle.com/javase/tutorial/java/generics/
I have an abstract class with an abstract method, the parameters for which I want to be final - that is, I do not want to allow implementations of the abstract class & method to reassign the parameter.
EDIT: The motivation for this is not immutability per se, which is more to do with the design of the objects. (In fact, in my use case, the parameter is collection which will be mutated in the implementation of the abstract method.) Rather, I want to communicate to anyone implementing my abstract class/method that these variables should not be reassigned. I know that I can communicate that via the java-doc, but I was looking for something more contractual - that they would have to follow, rather than just be guided to follow.
In a non-abstract method, I can do this using the final keyword - for example:
public class MyClazz {
public void doSomething(final int finalParameter){
finalParameter++; // compile error - cannot assign a value to final variable
}
}
However, if I use the final keyword in an abstract method, this does not form part of the contract - that is, implementations of the abstract method do not require the final keyword, and the parameter can be reassigned:
public abstract class MyAbstractClazz {
public abstract void doSomething(final int finalVariable);
}
public class MyExtendedClazz extends MyAbstractClazz {
#Override
public void doSomething(int finalVariable) { // does not require final keyword
finalVariable++; // so the variable is modifiable
}
}
As pointed out in answers to this SO Question, the final keyword does not form part of the method signature, which is why the implementation of the abstract class does not require it.
So, there are two questions:
Why is the final keyword not part of the method signature? I understand that it isn't,
but I want to know if there's a particular reason why it isn't.
Given that the final keyword is not part of the method signature, is there an alternative way of making parameters in an abstract method unassignable?
Other research:
this SO question touches on the same issue, but doesn't either of my two questions. In fact, the second question is explicitly asked, but does not receive an answer.
lots of questions/blogs etc. on the final keyword refer to "the final word". However, with respect to this question, the relevant comment is as follows (which, while useful, doesn't address my two questions):
Note that final parameters are not considered part of the method signature, and are ignored by the compiler when resolving method calls. Parameters can be declared final (or not) with no influence on how the method is overriden.
I have an abstract class with an abstract method, the parameters for which I want to be final - that is, I do not want to allow implementations of the abstract class & method to reassign the parameter.
Why not? That's an implementation detail. It's unobservable to the calling code, so there's no reason why the abstract method should specify it. That's why it's not part of the method signature, either - just like synchronized isn't.
A method should implement its documented contract - but how it chooses to do so is up to it. The contract can't say anything useful about the finality of a parameter, as Java always uses pass-by-value.
Parameters are passed by value, if you call the method using certain variable, this variable wont get modified even if you reassign the parameter inside the method, that's why it doesn't make sense for final to be part of the contract.
A service from external API which I am not allowed to modify returns me
MyClass instance = ServiceUtil.getThing();
I would like to extend this returned class and Add/Override a method but leave intacts the others, say 150 methods.
private class MyWrapperClass extends MyClass(){
public MyWrapperClass(){super();}
#Override public String toString(){ return "Blocked toString"; }
}
Is there any way to force this "casting" from the returned MyClass instance to my newly particular subtype??
NOTE: Please, not suggest the approach of making a constructor, passing the original object and having to copy and implement the 150 methods to call the wrapped object
If MyClass is an interface look at java.lang.reflect.Proxy and java.lang.reflect.InvocationHandler.
You can implement a dynamic proxy that always does the same. It is, always pass control to your original implementation... except when method X is invoked.
Something like:
class MyHandler implements InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args) {
if (method is the one you want to change) {
do whatever
else
return method.invoke(originalObject, args);
}
}
Note: you must create this proxy implementation anyway:
MyClass original = ServiceUtil.getThing();
MyClass proxy = (MyClass) Proxy.newProxyInstance(
MyClass.class.getClassLoader(), // classloader to use
new Class[] { MyClass.class }, // interfaces to implement
new MyHandler()); // who does the dirty work when methods are invoked
I hope I get you right: you have a
MyClass instance = ServiceUtil.getThing();
but want something like
MyWrapperClass instance = (MyWrapperClass) ServiceUtil.getThing();
(which obviously doesn't work, even though MyWrapperClass extends MyClass).
The solution is to create a new instance of MyWrapperClass based on the MyClass and, sorry to say that, using the constructor is a good approach (public MyWrapperClass(MyClass myClass)).
Please, not suggest the approach of making a constructor, passing the original object
and having to copy and implement the 150 methods to call the wrapped object
You mean to say that "decoration" is not an option you would like to look at right?
But decoration will be a problem to you if MyClass is an interface type where you have to define those 150 odd methods, delegating the 149 method calls onto the decorated and overriding that one method.
If MyClass is a class type, then you don't need to write those 149 methods, right? or Did I get you completely wrong?
Consider the following code from The Java Programming Language book
public class MyClass extends HerClass implements Cloneable {
public MyClass clone()
throws CloneNotSupportedException {
return (MyClass) super.clone();
}
// ...
}
When the overiding clone() function already species the return type as MyClass then what is the requirement of specifying it again in the return statement ?
Also since the clone of Myclass's super class object is being created (cause clone() is being called wrt superclass), how can it be of Myclass type?
Thanks in advance
Because clone() returns an object of class Object, and you must cast it to the correct type. But you know it is an object of type MyClass, so that cast is correct.
In theory you're right: as you have to specify the type of function return values the compiler could try and perform the correction automatically. On the other hand requiring an explicit conversion helps identify possible errors.
Unless you have specific requirements the clone() method of the Object class already does the right thing, i.e. it creates an object of the correct class and copies all the non-static attributes in the cloned object. However it cannot return it as a derived type because at compile time that type is not known to the Object class itself.
It is true that the clone() method could have been provided automatically for all classes, but sometimes you don't want it to be available and at other times you want to override the default behaviour; for instance you might have an id attribute in your class that you want to be different for each instance of your class even when cloned. Having to override the clone() method gives you a place where you can implement such functionality.
This is because the clone() method in Object returns an Object. However you can return your subclass in clone() because it extends an Object. If the method in MyClass looked like this
public Object clone()
Then it would still be a valid cloneable object and it would work. You wouldn't need to cast anything. The interface, Cloneable is just a marker interface, which means it doesn't actually have any methods.
Your easy question first: why is super.clone() cast to MyClass? That's because the declaration of HerClass.clone() specified a returned value of HerClass, so you must cast it to the right type.
Now, for the more difficult question: how can super.clone() actually return an instance of MyClass? I actually had a hard time finding the answer, but I did somewhat find an answer in Effective Java by Joshua Bloch. There is still some "magic" in the background of Object.clone() that I don't quite understand.
Item 11 from the book:
In practice, programmers assume that if they extend a class and invoke
super.clone from the subclass, the returned object will be an instance
of the subclass. The only way a superclass can provide this
functionality is to return an object obtained by calling super.clone.
If a clone method returns an object created by a constructor, it will
have the wrong class. Therefore, if you override the clone method in a
nonfinal class, you should return an object obtained by invoking
super.clone. If all of a class’s superclasses obey this rule, then
invoking super.clone will eventually invoke Object’s clone method,
creating an instance of the right class.
I originally tried to answer your question by writing a program without knowing you always had to call super.clone(). My homemade clone method for HerClass was returning a new instance of HerClass generated from a constructor (new HerClass()). The code compiled, but it failed at execution when I was trying to cast (MyClass) super.clone(). Only methods that are chained down from Object.clone() can return a value that is an instance of one of their subtype.
Note that if HerClass.clone() is not explicitly implemented, by default it simply returns Object.clone(). The default method has protected access, but since you are calling it from a subclass, it's not a problem.