How can I access a method of an "unnamed" class? - java

public class Test {
public static void main(String[] args) {
DemoAbstractClass abstractClass = new DemoAbstractClass() {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
};
abstractClass.runner();
/**
* I want to access getVal method here
*/
}
}
abstract class DemoAbstractClass {
public void run() {
System.out.println("running");
}
public abstract void runner();
}
Here, I'm declaring an abstract class DemoAbstractClass. I can obviously create a new class that extends this class and add this method to it. But, I would prefer not doing that in my scenario.
Is there any other way to access getVal method in above code??

You can't. You need to make a proper (non-anomous) class out of it. Make it an inner private class if you want to limit its scope.
Alternatively, you could use a StringBuffer and share a referense to it between the methods. Not extremely clean however.
Related question:
Accessing inner anonymous class members

Short of using reflection, you cannot as you have no access to the concrete type of the object to be able to bind the methodcall to
If you don want to do something like this in a sane manner, declare a named class and use that as the type of abstractClass

Unfortunately, if you cannot name the type, you cannot access the methods at the language level.
What you can do, though, is use the reflection API to get a Method object and invoke it on this object.
This, however, is pretty slow. A private class or private interface would be much faster.

I can obviously create a new class that extends this class and add this method to it.
You've already done this; the end result was an anonymous inner class: new DemoAbstractClass() { ... }; If you just moved that declaration into its own class -- you can even make it a private class -- you can access getVal.
Per your example above:
public class Test {
public static void main(String[] args) {
DemoClass abstractClass = new DemoClass();
abstractClass.runner();
/**
* I want to access getVal method here
*/
abstractClass.getVal(); // can do this here now
}
private class DemoClass extends DemoAbstractClass {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
}
}
}

Another option is to make a StringBuilder a member of the main method and use the closure nature of anonymous inner methods:
public static void main(String[] args) {
final StringBuilder value = new StringBuilder();
DemoAbstractClass abstractClass = new DemoAbstractClass() {
#Override
public void runner() {
value.append( "test" );
System.out.println(val);
this.run();
}
};
abstractClass.runner();
// use val here...
String val = value.toString();
}

Related

How to avoid creating object only referenced by inner class in Java?

I'm trying to create some system with inner class. My code can be summarized to something like this.
public abstract class A {
public abstract void doSomething();
}
public class B {
public final ArrayList<A> list=new ArrayList<A>();
public B(){
}
}
public class C {
private int i;
public C(B b){
b.list.add(new A(){
public void doSomething(){
i++;
}
});
b.list.add(new A(){
public void doSomething(){
System.out.println(i);
}
});
}
}
public static void main (String[] arg) {
B manager=new B();
new C(manager);
new C(manager);
new C(manager);
}
A is abstract class that will be inherited as inner class (in my original code it is listener class), B is some kind of manager class that hold list of As, and C hold data it's data should be only modified or read by it's inner class and upon initialization it add A to the class B. Code itself works fine. But problem is as there will be various kinds of C something like C2, C3 that does different thing and this leads to my code overwhelmed with thousands of unassigned object new C(manager); this make debugging extra hard and code looks really ugly. So it seems to me my approach in the first place was wrong but have no idea how to avoid this. So how should I change my approach to not have thousands of unassigned objects?
My suggestion is: try not to use constructors to do operations that depend on state (i). Use static functions, and save the state in a separate class (we call it a “context”).
import java.util.ArrayList;
public class Demo {
// A
abstract static class InnerListener {
public abstract void onEvent();
}
// B
static class ListenerManager {
public final ArrayList<InnerListener> listeners = new ArrayList<InnerListener>();
}
static class SideEffectContext {
public int i = 0;
}
// C
static class ListenerUtil {
public static void setupListeners(ListenerManager manager, SideEffectContext context) {
manager.listeners.add(new InnerListener() {
public void onEvent() {
context.i++;
}
});
manager.listeners.add(new InnerListener() {
public void onEvent() {
System.out.println(context.i);
}
});
}
}
public static void main(String[] arg) {
var manager = new ListenerManager();
var ctxA = new SideEffectContext();
var ctxShared = new SideEffectContext();
ListenerUtil.setupListeners(manager, ctxA);
ListenerUtil.setupListeners(manager, ctxShared);
ListenerUtil.setupListeners(manager, ctxShared);
}
}

How to create constructor in java parameterized with class?

I want to have a class to run other classes in java, like constructor parameterized with a class to run that class later on, similar to this
class MyClass{
Class classToRun;
public MyClass(Class c) {
super();
this.classToRun = c;
}
public void runClass(){
classToRun.someStaticMethod();
}
}
where classToRun possible classes doesn't have a common ancestor, but all have method someStaticMethod, and have no idea about MyClass, which runs them.
But there are problems, like inner classes cannot have static methods, classes cannot be cast Class, etc.
There are solutions for parameterized with class methods, like
How do I pass a class as a parameter in Java?
Passing a class as an argument to a method in java
but not for constructors.
What is the proper solution to do this?
Use lambdas and pass the method reference: they match on the method signature. For void someStaticMethod() you can use Runnable.
class MyClass{
private final Runnable methodToRun;
public MyClass(Runnable someStaticMethod) {
methodToRun = someStaticMethod;
}
public void runClass(){
methodToRun.run();
}
}
new MyClass(SomeClass::someStaticMethod).runClass();
You cannot enforce that the method passed has the right name, but looks even neater IMHO.
You need to understand what generics are.
interface
public interface SomeInterface {
void someStaticMethod();
}
use
class MyClass<T extends SomeInterface>{
T classToRun;
public MyClass(T c) {
super();
this.classToRun = c;
}
public void runClass(){
classToRun.someStaticMethod();
}
}
As 2 of 3 answers were not to the point, I decided to publish fixed versions of both answers as far as they can be fixed.
The f1sh version from the above should like follows:
public class ClassToRunOthers {
Class classToRun;
public ClassToRunOthers(Class c) {
this.classToRun = c;
}
public void runClass() throws Exception {
Optional<Method> method = Arrays.stream(classToRun.getDeclaredMethods()).filter(m -> m.getName().equals("someStaticMethod")).findFirst();
if(!method.isPresent()) {
throw new RuntimeException();
}
method.get().invoke(null);
}
public static void main(String[] args) throws Exception {
ClassToRunOthers mc = new ClassToRunOthers(SomeClass.class);
mc.runClass();
}
}
class SomeClass {
static void someStaticMethod() {
System.out.println("test");
}
}
The zwei solution above can not be fixed without reflection, as generics is not to the point. Evan if you try to parametrize not with SomeInerface (because SomeClass does not extend a common SomeInterface), but with Object, it is still won't solve the problem:
public class MyClass<T extends Object> {
T classToRun;
public MyClass(T c) {
super();
this.classToRun = c;
}
public void runClass() {
// classToRun.someStaticMethod(); // Cannot resolve method 'someStaticMethod' in 'T'
}
public static void main(String[] args) {
MyClass mc = new MyClass(SomeClass.class);
}
}
class SomeClass {
static void someStaticMethod() {
System.out.println("test");
}
}
This can be fixed like the above, via reflection.
I believe, it can be done with annotations in some elegant way, and may be someone will share us with such a solution or I will do it by myself as time permits.
By now for myself, a solution with saving class name in the String in constructor next day after the question been asked did the trick.
You will have to use reflection if you want to execute a method when you only have the Class instance.
In the code below, runClass finds the method of the class using it's name as a String, then executes it. This code assumes that the method is static, also ignoring any Exception handling.
The following code prints "test":
class MyClass {
Class classToRun;
public MyClass(Class c) {
this.classToRun = c;
}
public void runClass() throws Exception {
Optional<Method> method = Arrays.stream(classToRun.getDeclaredMethods()).filter(m -> m.getName().equals("someStaticMethod")).findFirst();
if(!method.isPresent()) {
throw new RuntimeException();
}
method.get().invoke(null);
}
}
class Main {
public static void main(String[] args) throws Exception {
MyClass mc = new MyClass(Main.class);
mc.runClass();
}
static void someStaticMethod() {
System.out.println("test");
}
}

Access class variable using Interface type

I've following class
class MyClass implements Intrfc {
String pickmeUp = "Its Me";
public static void main(String[] args){
Intrfc ob = new MyClass();
ob.pickmeUp; ---> How can I access this way ?
}
}
Is there any way to access class variable using Interface type ?
Is there any way to access class variable using Interface type ?
No. That is the whole point of an interface.
And yes, interfaces only give you behavior (methods), not "state" (variables/fields). That is how things are in Java.
Of course, you can always use instanceof to check if the actual object is of some more specific type, to then cast to that type. But as said, that defeats the purpose of using interfaces!
No, you can't access the class variable using interface type, but the interface can define method that can access to the variable.
interface Intrfc {
public String getPickmeUp();
}
class MyClass implements Intrfc {
String pickmeUp = "Its Me";
public String getPickmeUp(){
return pickmeUp;
}
public static void main(String[] args){
Intrfc ob = new MyClass();
ob.getPickmeUp();
}
}
In this definition:
class MyClass implements Intrfc {
String pickmeUp = "Its Me";
}
the field pickmeUp is not even a member of Intrfc interface, so there is no possibility to reach for it using just the interface. pickmeUp is a member of a concrete class - MyClass.
If you want to use the method of a class using the object of an interface you can do it as follows:
//Interface:
public interface TestOne {
int a = 5;
void test();
static void testOne(){
System.out.println("Great!!!");
}
default void testTwo(){
System.out.println("Wow!!!");
}
}
//-------------------
//Class implementing it:
package SP;
public class TestInterfacesImp implements Test1, TestOne{
#Override
public void test() {
System.out.println("I Love java");
}
public void testM() {
System.out.println("I Love java too");
}
public static void main(String[] args) {
TestOne.testOne();
TestOne obj = new TestInterfacesImp();
obj.testTwo();
TestInterfacesImp objImp = new TestInterfacesImp();
objImp.test();
((TestInterfacesImp) obj).testM(); //Here casting is done we have casted to class type
}
}
Hope this helps...

Java: share object reference without passing as parameter

I have an ObjectFactory and a specialized case of implementation of that factory. I can't change the interface, that has 0 argument.
In one of the implementation I have to read a file and load some data. To pass the filename I can use the system properties because all I need to share is a string.
But in the other implementation I must start not from a file but from a memory structure. How can I do to pass the object (then I think the object reference) to the factory? Other methods? No way I serialize the object on a file and after I read it again because what I want to avoid is right the I/O footprint.
Thanks
OK, more informations:
This is the interface and the abstract factory I have to implement
public abstract interface A
{
public abstract Set<Foo> getFoo();
public abstract Set<Bar> getBar();
}
//this is otherpackage.AFactory
public abstract class AFactory
{
public static AccessFactory newInstance()
{
return a new built instance of the factory
}
public abstract A newA();
}
This is my implementation with my problem:
public class AFactory extends otherpackage.AFactory
{
#Override
public Access newA()
{
return new AA();
}
}
public class AA implements A
{
protected AA()
{
this.objectReferenceIWantToSaveHere = I retrieve from the shared memory zone;
use the object
}
}
Now I'd like to do something like this:
B b = something I built before
save b in a shared memory zone or something like that
otherpackage.AFactory f = mypackage.AccessFactory.newInstance();
A a = f.newA();
And inside the f.newA() call I'd like to access to the b object
Can't you simply use a constructor?
interface ObjectFactory { Object create(); }
class SpecialFactory implements ObjectFactory {
private final Object data;
public SpecialFactory(Object data) { this.data = data; }
#Override public Object create() { return somethingThatUsesData; }
}
Ass assylias proposes, you can pass the reference to the constructor. Or if you know where to find the reference, you could just ask for it before you use it? E.g. data = dataBank.giveMeTheData()
Agree it would help to get some more context around what you are doing... but could you use a shared static class in which your calling code places info into the static class, and your interface implementation references this same static class to obtain either the object and/or instructions?
So here's a client class. It has the entry point..and wants to pass an object to the interface implementer but it can't pass it directly...So it set's object it wants to pass in the MyStaticHelper.SetSharedObject method.
public class Client {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String mySharedObject = "Couldbeanyobject, not just string";
// Set your shared object in static class
MyStaticHelper.SetSharedObject(mySharedObject);
InterferfaceImplementer myInterfaceImplementer = new InterferfaceImplementer();
//
myInterfaceImplementer.RunMyMethod();
}
Here is the code for the static helper...
public class MyStaticHelper {
private static Object _insructionsObject;
public static void SetSharedObject(Object anObject)
{
_insructionsObject = anObject;
}
public static Object GetSharedObject()
{
return _insructionsObject;
}
}
and finally the the class that you call that uses the static helper to get the same object.
public class InterferfaceImplementer {
// no objects
public void RunMyMethod()
{
System.out.println(MyStaticHelper.GetSharedObject());
}
}
Again this works in a very simple scenario and wouldn't stand up if more than one implementer needs to be called simultaneously as this solution would only allow one obj to be in the static helper class.

get caller class name from inherited static method

I have following classes (note that methods are static):
class Base
{
public static void whosYourDaddy()
{
Class callerClass = // what should I write here to get caller class?
System.out.print(callerClass.getName());
}
}
Class A extends Base
{
public static void foo()
{
A.whosYourDaddy();
}
}
Class B extends Base
{
public static void bar()
{
B.whosYourDaddy();
}
}
And when I call:
A.foo();
B.bar();
I'd like to get output:
AB instead of BaseBase. Is it even possible with static methods (in Java 7)?
What you can do, but shouldn't :) is use the Throwable getStackTrace method. Aside from the smell, this is pretty slow, because getting the stack trace isn't that fast. But you will get an array of StackTraceElement, and each one will contain the class of teh class that is calling it (and you can also get the file and line, and if you separate the two with a : you can get a clickable link in eclipse, not that I'd ever do such a thing...).
Something like
String className = new Throwable().getStackTrace()[1].getClassName();
Hope that helps :)
private static class Reflection {
private static final SecurityManager INSTANCE = new SecurityManager();
static Class getCallClass() {
return INSTANCE.getCallClass(2);
}
private Reflection() {
}
private static class SecurityManager extends java.lang.SecurityManager {
public Class getCallClass(int i) {
Class[] classContext = getClassContext();
if (i >= 0 && i + 1 < classContext.length) {
return classContext[i + 1];
}
return null;
}
};
}
Is it even possible with static methods (in Java 7)?
No, Static methods aren't inherited. Only non-static methods are inherited.
In your case change Base (and subclasses) as follows:
class Base
{
public void whosYourDaddy()
{
Class<?> callerClass = getClass();
System.out.print(callerClass.getName());
}
}

Categories