Java: Return class (Not an instance) - java

Is it possible to return in a static method a class? I will explain...
I have:
public class A { public static void blah(){} }
public class B { }
I want to create a static method in B witch returns A. So you can do:
A.blah();
And
B.getA().blah();
This, without creating an instance of A. Just use it static methods.
Is this possible?

This is a rebuttal of #irreputable's answer:
public class B {
public static A getA(){ return null; }
}
B.getA().blah(); //works!
It "works", but probably not in the sense that you expect, and certainly not in a useful way. Let's break this down into two parts:
A a = B.getA();
a.blah();
The first statement is returning a (null in this case) instance of A, and the second statement is ignoring that instance and calling A.blah(). So, these statements are actually equivalent to
B.getA();
A.blah();
or (given that getA() is side-effect free), just plain
A.blah();
And here's an example which illustrates this more clearly:
public class A {
public static void blah() { System.err.println("I'm an A"); }
}
public class SubA extends A {
public static void blah() { System.err.println("I'm a SubA"); }
}
public class B {
public static A getA(){ return new SubA(); }
}
B.getA().blah(); //prints "I'm an A".
... and this (I hope) illustrates why this approach doesn't solve the OP's problem.

I'm going to guess that the reason you ask this is that you want B to return many different classes with different behaviours - not just A.
You probably want to use an interface for what you're doing instead.
interface IA {
void blah();
}
public class B {
IA getA1() {
return new IA {
void blah() {
...code...
}
}
}
IA getA2() {
...
}
IA getA3() {
...
}
}
myCallingMethod {
B.getA1().blah();
B.getA2().blah();
B.getA3().blah();
}

No this is not possible. You have two options:
B.getA() returns an instance of
A, and blah() will be a non-static
method.
Directly call A.blah().

People are saying it's impossible, and that's kind of true, but if you use the reflection API you can do something close to that.
Here's how you could do it.
You have a class that does this.
public class B {
Class a
public static Class getA(){
return a;
}
}
then to call blah you do:
try{
Method m = B.getA().getDeclaredMethod("blah");
m.invoke(null);//for a static method, you can invoke on null
}
Catch(Exception e){
// see documentation for list of exceptions
}
So, why would you want to do this? Well, if you do it this way you can change the class A at So getA() could return A, B, C or D, all with different blah() functions. I'm not really sure what purpose that would serve, but if you want to do it, you can.
see:
Class.getDeclaredMethod() and Method.invoke() for more info.
I haven't tried this, so you might need to do some tweaking.

No, this is not possible. You can only return a reference to an instance of a class. The closest you can get to this is to return a reference to a variable of type Class. The question is: why do you want this? What problem are you trying to solve? There may be a better solution.

Even if it would be possible, it won't be of much use. The call A.blah() doesn't create an instance of A. It's a static method with no need for an instance.
And you can't use interfaces to implement static methods. So what should it be good for?

If you don't want to have an instance of A, then let B call blah() directly. I.e.
class B {
void blah() {
A.blah();
}
}

public class B {
public static A getA(){ return null; }
}
B.getA().blah(); //works!
EDIT
It is true that it is equivalent to
B.getA();
A.blah();
Except they look quite different. Imagine you have a chain of these.
I checked out org.apache.commons.cli.OptionBuilder and personly I wouldn't do it that way, but the author has his case. The API is used only in the beginning of a program, in a single thread.
API designers sometimes have to make some magic moves, don't be too judgemental.

You can return a Method using reflection which you can invoke() later.
However, it sounds like you are trying to do something which should be done another way.
Why are you trying to do this?

Related

Surprising access to fields with Java anonymous class

I'm trying to better understand the concept of anonymous classes in Java. From other answers on this website, I learned that an anonymous class can access non-final fields of the enclosing class using OuterClass.this.myField.
I made the following simple test case with an interface, AnonInt, and a class AnonTest with a method foo which returns an instance of an anonymous class implementing AnonInt. Dspite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
public interface AnonInt {
void print();
}
public class AnonTest {
private int a;
public AnonTest(int a) {
this.a = a;
}
public AnonInt foo() {
return new AnonInt() {
public void print() {
System.out.println(a);
}
};
}
public static void main(String[] args) {
AnonTest at = new AnonTest(37);
AnonInt ai = at.foo();
ai.print();
}
}
Despite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
Since the reference to a is unambiguous in your context, the two expressions reference the same field.
Generally, AnonTest.this is required in a very specific context - when your method needs to access AnonTest object itself, rather than accessing one of its members. In case of your program, this is unnecessary: the compiler resolves the expression a to the object AnonTest.this.a, and passes it to System.out.println.

Why it is called runtime polymorphism?

I am extending a class but I am not able to figure out why the JVM decides only at runtime which method to call. I mean when I do A obj=new B();, isn't it obvious that the method in B will be called ?
Maybe it is not obvious for compiler but I want to know the details.
Code is as follows :
class A
{
String getName(String name) {
return "super";
}
}
class B extends A
{
#Override
String getName(String name) {
return "sub";
}
}
public class Overload
{
public static void main(String args[]) {
A obj=new B();
System.out.println(obj.getName(null));
}
}
A compiler can only able to check their types and it's functionality is limited. Hence it cannot actually run and see the program output. That is why it belong to run time.
Compiler check it's type, and runtime bind it's functionality.
You know it holds a reference of B, because the complexity of code here is simple.
What if you had class 'C' also extending from class 'A' and if the responsibility of initializing obj is with some other class or may be some config.
Unlike as in compile-type polymorphism where we as well as the compiler can see the single statement and decide which method can be called.
Lets see this scenario:
public abstract class A {
public abstract void sayHello();
}
public class B extends A{
public void sayHello(){
System.out.println("B says Hello!");
}
}
public class C extends A{
public void sayHello(){
System.out.println("C says Hello!");
}
}
public class FactoryA{
public static A getInstance(String type){
if("B".equals(type)){
return new B();
}
else if("C".equals(type)){
return new C();
}
}
}
Lets say that now you ask the factory to get instance based on the String parameter, like this:
A a = FactoryA.getInstance("B"); // the string can come user-input
a.sayHello();
In this output will be "B says Hello!", because the instance you get from Factory's method is an instance of B, which depends on the String parameter passed to it.
In this case it may not be known at the run time which method will be called (B's sayHello() or C's sayHello()). That's why it is called runtime polymorphism.
Because the decision was taken at runtime.

Check if class implements interface

Here is an example:
There are a basic class(A) which handles lots of different classes (lets say B,C,D all extending P). In class A I need to call a function like:
public void doSmth(P variable) {
B b = (B)variable;
b.getSomeImportantInfo();
}
For this I am trying to add an interface (I) and define B, C, D implement it.
The trouble is, that doSmth will work with all this classes (B,C,D) and I dont want all of them implement this interface. So I'm trying to do something like this:
public void doSmth(P variable) {
if(variable instanceof I) {
((I)variable).getSomeImportantInfo();
}
}
But this does not work, cause it says it cant cast variable to I.
How can I achieve needed behavior? Also, I can not modify P and make it implement I.
I think it too later, but:
public static boolean isImplementsInterface(Class interfaze, Class clazz) {
for (Class c : clazz.getInterfaces()) {
if (c.equals(interfaze)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
System.out.println(isImplementsInterface(CharSequence.class, String.class));
}
I think you don't need to explicitly typecast the variable to I.
Once you checked if it is instance of 'I', directly call the method and let the program decide at runtime..which will be invoked depending upon the actual object, reference variable refers.

Call method from instance

Let's say I have two classes, A and B, in turn have some methods, something() and nothing() and an instance of B is created in A, as
public class A {
public A() {
B b = new B();
b.nothing();
}
public void something() {
...
}
}
A calling b.nothing() is all standard stuff, but is there any means which by instance b can call a.something(), assuming the instance of A is called a. If not, why is this conceptually wrong?
I don't think there's anything conceptually wrong with this.
However, for the mechanics to work, b needs to know which instance of A to call something() on. For this, either B's constructor, or its nothing() method, needs to take an A reference as an argument.
example 1:
public class B {
public void nothing(A a) {
...
a.something();
...
}
}
example 2:
public class B {
private final A a;
public B(A a) {
this.a = a;
}
public void nothing() {
...
this.a.something();
...
}
}
example 3:
There is a third way, applicable in some circumstances. If B is an inner class of A, it has an implicit reference to its associated instance of A.
public class A {
public void something() { ... }
public class B {
public void nothing() {
...
something();
...
}
}
}
is there any means which by instance b can call a.something()
You can't get hold of the caller in a method so, no, there's no way to do that.
If not, why is this conceptually wrong?
Two issues come to my mind immediately:
What would the type of the caller be? Since anyone could call b.nothing(), you can't assume more than that it's an Object which would result in lots of ugly down casts.
The implementation of b.nothing() shouldn't care about who's calling him. What happens if you refactor A and move the call to b.nothing() to some other class? It would be quite surprising if b.nothing() all of a sudden stopped working.
The only way b.nothing() can call a.something() is if you tell the instance of B about the instance of A. For example:
b.nothing(this);
where B.nothing looks like:
public void nothing(A a)
{
// Do other stuff
a.something();
}
Alternatively, you could pass in this in the constructor to B, which would keep hold of the reference:
B b = new B(this);
b.nothing();
Note that letting this escape during a constructor call is generally a bad idea - you're letting B.nothing() call A.something() on an object which isn't fully initialized yet - its constructor hasn't finished executing. That can lead to undesirable and hard-to-diagnose behaviour sometimes.
To do this, b would require a reference to a. There are two ways to provide that:
Pass such a reference in the constructor of B or give B an appropriate setter.
If B is an inner class of A, then it has such a reference implicitly.

Java Inheritance Question

I Have something similar to this setup:
public class Base {
public String getApple() {return "base apple"};
}
public class Extended extends Base{
public String getApple() {return "extended apple"};
}
Somewhere else in the code I have this:
{
Base b = info.getForm();
if (b instanceof Extended){
b = (Extended) b;
}
System.out.println(b.getApple()); // returns "base apple" even when if clause is true why??
}
How do I accomplish that?
First:
if (b instanceof Extended){
b = (Extended) b;
}
does absolutely nothing. You are basically saying b = b, which says nothing. You are not even changing the reference.
Second, getApple() will always be dynamically bound, and the "extended apple" should always be called - given that the subclass is truly extending the base class, and the method is truly overridden.
Basically what you need to do, in order to accomplish correct getApple() behavior:
remove the if clause. it does nothing.
make sure your class is indeed extending the base class
make sure the getApple() method is overriding the base class method. (use the #override annotation if you are not sure)
As written, your code will not compile, which makes me think that your problem is elsewhere. Your return statements don't have semicolons at the end of them. Rather, they appear after the }. It's possible you had some other problem (maybe your subclass misspelled getApple()), but you're still using your old class files because your new stuff isn't compiling.
This code works:
class Base {
public String getApple() { return "base apple"; }
}
class Extended extends Base {
public String getApple() { return "extended apple"; }
}
public class Test {
public static void main(String[] args) {
Base b = new Extended();
System.out.println(b.getApple());
}
}
Console:
#javac Test.java
#java Test
extended apple
First of all, that if block should never be necessary. It's basically a no-op.
Second, this isn't your real code, because it doesn't even compile. You're missing semicolons after the return statements.
I suspect that your problem is that your real code has a typo that's making the signatures of the two getApple methods different. This means that Extended has two methods: the one inherited from Base and the one with a different signature in itself. Since you're calling with the signature of the Base.getApple method, you're always getting that behavior. This is only a guess though, as your posted code does not exhibit the problem you describe.
Yuval is right that your cast in the if block has no effect. You might try combining your last statement with the if:
if (b instanceof Extended)
{
// Prints "extended apple" if reached.
System.out.println(((Extended)b).getApple());
}
Add #Override to the method in your subclass and recompile. This will help you find out if you're not actually overriding the method you think you are.
i.e.
public class Base {
public String getApple() {return "base apple";}
}
public class Extended extends Base{
#Override
public String getApple() {return "extended apple";}
}
The only way to get that behavior is to return super.getApple() in your extended class, which is effectively the same as not overriding it in the first place. The only way this could help is if you pass in an argument to decide which to return. Not saying thats good design...
Forgot to mention that, as Yuval said, the cast does nothing to the object.
You should investigate what is constructing your instance that is returned from info.getForm(). You may want to make the Base abstract to prevent it from being instantiated and you'll quickly see where construction is happening.
Are you sure your code example provided in your question EXACTLY matches the code your are using? The reason I ask is that the behavior you are describing happens when you access a public FIELD instead of a public METHOD with an object pointer.
For example:
public class BaseClass {
public String baseField;
public BaseClass() {
baseField = "base";
}
public String getBaseField() {
return baseField;
}
}
public class SubClass extends BaseClass {
public String baseField;
public SubClass () {
baseField = "sub";
}
public String getBaseField() {
return baseField;
}
}
public class MainClass {
public static void main(String[] args) {
BaseClass baseObject = new BaseClass();
SubClass subObject = new SubClass();
System.out.println(baseObject.getBaseField());
System.out.println(subObject.getBaseField());
System.out.println(baseObject.baseField);
System.out.println(subObject.baseField);
System.out.println(((BaseClass)subObect).getBaseField());
System.out.println(((BaseClass)subObect).baseField);
}
}
Will print out:
base
sub
base
sub
sub
base
When you call a method, the JVM will start at the bottom of the inheritance hierarchy and call the appropriate method. When you reference a field instead, it uses the class of the pointer instead of walking up the class hierarchy to resolve the value. The behavior of the field reference matches what you're seeing, which is why I ask for clarification/verification.

Categories

Resources