I have an interface ParentInterface and have multiple enums that implement it: ChildEnum1 and ChildEnum2. I have a method to which I pass the ParentInterface as a parameter.
Based on what ChildEnum is passed to this method, I want to get the size of the enum. How can I do this? The values.length() method works only on enums, but we are only passing in the ParentInterface to the caller.
How can we achieve this?
With reflection, using Class#getEnumConstants() (quick and dirty demo):
package com.stackoverflow.so21821751;
public class Test {
interface ParentInterface {
void someMethod();
}
static enum ChildEnum1 implements ParentInterface {
FOO, BAR, LOL;
#Override
public void someMethod() {
// something
}
}
static enum ChildEnum2 implements ParentInterface {
FOO, BAR;
#Override
public void someMethod() {
// something
}
}
public static void main(final String[] args) {
foo(ChildEnum1.BAR); // 3
foo(ChildEnum2.FOO); // 2
}
private static void foo(final ParentInterface i) {
System.out.println(i.getClass().getEnumConstants().length);
}
}
Related
I have two nested classes inside a class with the outer class extending another class. The structure is something like this.
public class EXTENSION_CLASS
{
public int Get_Value()
{
return(100);
}
}
public class OUTER extends EXTENSION_CLASS
{
public static class NESTED1
{
public void Method1()
{
int value=0;
value=Get_Value();
System.out.println("Method1: "+value);
}
}
public static class NESTED2
{
NESTED1 Nested1_Instance=new NESTED1();
public void Method2()
{
Nested1_Instance.Method1();
}
}
public void run()
{
NESTED2 Nested2_Instance=new NESTED2();
Nested2_Instance.Method2();
}
public static void main (String[] args)
{
OUTER New_Class=new OUTER();
New_Class.run();
}
}
I'm expecting the output: "Method1: 100". But, am getting the output: "OUTER.java:16: error: non-static method Get_Value() cannot be referenced from a static context value=Get_Value();". How can i make this working?
Cheers !
Rajesh.
One approach would be to have an instance of NESTED1 in NESTED2. For example:
private static class NESTED2
{
private NESTED1 nested1;
public NESTED2 (NESTED1 nested1) {
this.nested1 = nested1;
}
public void Method2()
{
nested1.Method1();
}
}
private static class NESTED2
{
public void Method2(NESTED1 nested1Instance)
{
nested1Instance.Method1();
}
}
That should do it with your class structure. Instead, with a modification like so....
private static class NESTED1
{
public *statc* void Method1()
{
...
}
}
private static class NESTED2
{
public *static* void Method2()
{
NESTED1.Method1();
}
}
... you could get away with no creation of objects.
If you make the methods static, you don't need to instantiate(create) a class object to call them first.
i'm trying to write anonymous inner class
interface Face{
void seeThis(String what);
}
class Eyes {
public void show(Face f){}
}
public class Seen {
public void test() {
Eyes e = new Eyes();
e.show(new Face() {
#Override
public void seeThis(String what){
System.out.print(what);
}
});
public static void main(String[] args) {
Seen s = new Seen();
s.test();
}
}
How to call seeThis() and how to pass parameter to it?
Method seeThis() belongs to Face class, which instance is anonymous and thus cannot be reached without storing reference to it. If you want to store a reference, you can do this in the following way:
public class Seen {
public Face face;
....
this.face = new Face() { ... };
e.show(this.face);
And then,
Seen s = new Seen();
s.face.seeThis();
Now, regarding passing the parameter. You have two options - declare parameter outside of anonymous class and make it final in order to be reachable by this anonymous class, or replace anonymous class with normal one and pass the parameter to its constructor:
Approach one:
final int parameter = 5;
...(new Face() {
#Override
public void seeThis() {
System.out.println(parameter);
}
});
Approach two:
public class MyFace implements Face() {
private final int parameter;
public MyFace(int parameter) {
this.parameter = parameter;
}
#Override
public void seeThis() {
System.out.println(parameter);
}
}
Then,
...
e.show(new MyFace(10));
Please help resolve an issue regarding generics. I tried many ways but it's still not working.
Problem is:
public static void main(String[] args) {
Utils.execute(new TestAction(), new TestCallBack());
}
Compiler show error:
The method execute(Action<?>, CallBack<?,Action<?>>) in the type Utils is not applicable for the arguments (ImplementClass.TestAction, ImplementClass.TestCallBack)
My classes is:
Action class:
public abstract class Action<R> {
public R getResult() {
return null;
}
}
TestAction class is:
class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
Callback class is:
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);}
TestCallback class is:
class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
And Utils class is:
public class Utils {
public static void execute(Action<?> action, CallBack<?, Action<?>> callback) {
}
}
Thanks a lot.
The second parameter of the execute method is CallBack<?, Action<?>>, and Action there means the Action class itself, subclass of it is not allowed. What you need there is - ? extends Action<?>, which means either Action or some subclass of it.
Try changing the method signature -
public static void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
Note:
Generics are not co-variant. Take for example a method as follows -
static void method(List<Object> l) {}
And an invocation as follows is not allowed -
method(new ArrayList<String>());
You need to change two things,
TestCallBack should be like this -
public static class TestCallBack implements CallBack<String, Action<String>> {
#Override
public void onCall(Action<String> action) {
}
}
and, Utils should be like this -
public static class Utils {
// You need to ensure the same type, not just try and accept anything.
public static <T> void execute(Action<T> action, CallBack<?, Action<T>> callback) {
}
}
or using inner classes of a class called Question -
public abstract class Action<R> {
public R getResult() {
return null;
}
}
public class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);
}
public class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
public class Utils {
public void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
}
}
public static void main(String[] args) {
Question question = new Question();
question.new Utils().execute(question.new TestAction(), question.new TestCallBack());
}
I would like to know how to create a contract with the caller for the Method parameter in the event the method has parameters itself. So that I use...
ClassA {
String string_ = "HI";
public static void subscribe(Object class, Method action) {
action.invoke(class, string_);
}
}
ClassB {
ClassB() {
ClassA.subscribe(this, this.getClass().getMethod("load", String.class));
}
public void load(String input) {
if(input.equals("HI")) {
...
}
}
}
I would like to know how to ensure the Method passed as "action" takes String as a parameter (i.e. ensure Method action == load(String){})? Is there something like this available:
public static void subscribe(Object class, Method action(String.class)) {
I want to do it in the method signature of subscribe so that it is obvious to the calling class (ClassB) that it needs to be prepared to take an argument of specified type.
EDIT: Updated last code bit so not to appear as if Method was generic. Poor choice of using <> on my part to represent an example of what I was trying to convey.
There's no way to do that in Java. The Method class is not generic, and there is no way for it to be so, because methods can take any number of parameters, and there is no way to make a class generic over a variable number of types.
Probably the best you can do is to declare your own type to use instead of Method:
public interface Action<T, P> {
public void invoke(T target, P parameter);
}
Then:
public static <T> void subscribe(T obj, Action<T, String> action) {
action.invoke(obj, string_);
}
ClassB() {
ClassA.subscribe(this, new Action<ClassB, String>() {
public void invoke(ClassB target, String parameter) {
target.load(parameter);
}
});
}
In C# there are means to achieve what you are trying to do but I can't think of a way to ensure that at compile time for java.
can you resort to using intefaces?
interface ILoader{
void load(String input);
}
ClassA {
String string_ = "HI";
public static void subscribe(ILoader loader) {
loader.load( string_);
}
}
ClassB implements ILoader {
ClassB() {
ClassA.subscribe(this);
}
public void load(String input) {
if(input.equals("HI")) {
...
}
}
}
Couldn't you use a slight modification of the Command Pattern?
puclic interface LoadCommand {
public load(String input);
}
public class ClassB implements LoadCommand {
public load(String input) {
// do stuff here
}
}
public class ClassA {
String myInput = "HI";
public static void subscribe(LoadCommand command) {
command.load(myInput)
}
}
The load method in the LoadCommand interface takes one String argument.
Sometimes, I create a decorator class like this:
class MyInterfaceDecorator implements MyInterface {
private final MyInterface delegate;
... constructor taking a MyInterface instance ...
#Override
public Object someInterfaceMethod(Some argument) {
return delegate.someInterfaceMethod(argument);
}
... etc, more methods here...
}
Can IntelliJ automatically create this class for me?
Update//
I noticed that IntelliJ has a "Generate" option for generating delegate methods. Create a new class:
public class MyDecoratorClass {
private MyInterfaceWithManyMethods myInterface;
}
Then mark myInterface, go to Menu > Code > Delegate Methods, select all methods you want to wrap and that's it.
//End of update
You could try the "Refactoring" -> "Replace inheritance with delegation" refactoring. It should be able to do this, like this. I call this "Code with Alt+Enter"
Go to the interface you want to generate a decorator for.
public interface MyInterfaceWithManyMethods {
void method1();
void method2();
void method3();
}
Press Alt+Enter, select "Implement Interface", give a name to your Decorator like "MyDecorator". This gives you
public class MyDecorator implements MyInterfaceWithManyMethods {
public void method1() {
}
public void method2() {
}
public void method3() {
}
}
In new class, select the class name, then "Refactor" -> "Replace inheritance with delegation", select your interface, tick all method names, press enter. You'll get:
public class MyDecorator {
private final MyObject object = new MyObject();
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
private class MyObject implements MyInterfaceWithManyMethods {
public void method1() {
}
public void method2() {
}
public void method3() {
}
}
}
Delete the inner class and the object initializer manually. You get:
public class MyDecorator {
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
Press Alt+Enter on the "object" which is now marked red, select "Create field", select MyInterfaceWithManyMethods.
public class MyDecorator {
private MyInterfaceWithManyMethods object;
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
Select the object variable, press Alt+Enter, select "Add constructor Parameter":
public class MyDecorator {
private MyInterfaceWithManyMethods object;
public MyDecorator(MyInterfaceWithManyMethods object) {
this.object = object;
}
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
You see it's all done with a few strokes of Alt+Enter. Reads like a lot of work but it can be done in less than 20 seconds. If you just have like 2 or 3 methods you might be faster with a live template, however if you have many methods with complex signatures you'll get a working result in about 20 seconds with this method. Alt+Enter simply rocks :D
You can perhaps add a file template like:
class ${NAME} implements ${INTERFACE} {
private final ${INTERFACE} delegate;
public ${NAME}(final ${INTERFACE} delegate) {
this.delegate = delegate;
}
and then when you have created the file using this template, just use
Alt+Inser and choice delegate Methods.
It's not perfect, but this could be a shortcut