so I have an abstract class and i'm willing to store all the values from the sub-classes in an ImmutableList. Here is an example on what I mean
public abstract class Test {
...
public abstract int getValue();
}
then the sub-class
public final class Example extends Test {
#Override
public int getValue() {
return 5;
}
}
Is there a way to store the Test#getValue() in an ImmutableList on start-up?
I tried doing something like
public abstract class Test {
public static final ImmutableList<Integer> VALUES = ImmutableList.of();
public Test() {
VALUES.add(getValue());
}
public abstract int getValue();
}
then print out the values in the VALUES list.
public static void main(String[] args) {
Test.LIST.forEach(System.out::println);
}
but it didnt work.
use an initializer block. It's possible to create a static block which will execute upon class load:
package foo.bar.baz;
import java.util.*;
public class Test {
static {
int MY_INT = 5;
List<Object> mylist = new ArrayList<Object>();
mylist.add(new Integer(MY_INT));
}
public Test() {
// ...
}
}
You can write in the main method like this :
Reflections reflections = new Reflections("com.TestClassExample");
Set<Class<? extends >> classes = reflections.getSubTypesOf(TestExampleClass.class);
Get all the names of the classes and then loop through all the classes, and then cast it in the your test class and , then using and storing the values dynamically in a variable like this.
private static List<Integer> immutableList = new ArrayList<Integer>();
Does this sound feasible for your problem ?
Related
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);
}
}
I'm working on making a programming language that compiles to JVM bytecode, and it highly relies on interfaces as types. I need some way to make an interface private, but have other code still be able to access it, but not make something that implements it.
I was thinking about using abstract classes with a private constructor, so only the classes in the same file would be able to access it. The only problem is that it is impossible to extend multiple abstract classes at once. For example, the structure of a simple compiled program would be this:
// -> Main.java
public class Main {
public static MyInteger getMyInteger() {
return new MyIntegerImpl(10);
}
public static void main(String[] args) {}
private interface MyInteger {
public int getValue();
}
private static class MyIntegerImpl implements MyInteger {
private final int value;
public int getValue() {
return value;
}
public MyIntegerImpl(int value) {
this.value = value;
}
}
}
And another file, in which there is a problem:
// -> OtherFile.java
public class OtherFile {
public static void main(String[] args) {
Main.MyInteger myInteger = Main.getMyInteger(); //Error: The type Main.MyInteger is not visible.
System.out.println(myInteger.getValue());
}
//I do not want this to be allowed
public static class sneakyInteger implements Main.MyInteger { //Error(Which is good)
public int getValue() {
System.out.println("Person accessed value");
return 10;
}
}
}
The reason why I want to do this is so one person can not mess up any other person's code by providing their own implementations of things that should be only implemented by that other person.
Any help would be much appreciated.
I'm pretty sure that you should think again about what you are trying to do and change approach, but the answer for your question is to add to the interface some empty void method that is getting the parameter of the inner private class specific for the wrapper class
public class Test {
private class InnerPrivateClass {
private InnerPrivateClass() {}
}
public interface MyInteger {
int getValue();
void accept(InnerPrivateClass c);
}
private class MyIntegerImpl implements MyInteger {
#Override
public int getValue() {
return 0;
}
#Override
public void accept(InnerPrivateClass c) {}
}
}
However, as I said, I don't like this and for me it means that your idea is broken
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());
}
}
I have an abstract class MyClass with a static method to populate given collection with a number of MyClassDescendant objects. This method should call a static getRandom() method of MyClassDescendant to get object instances.
My current code looks like this:
public static void populate(Collection<MyClass> coll, Class<? extends MyClass> cl, int num) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
for (int i = 0; i < num; i++) {
Method m;
m = cl.getMethod("getRandom");
coll.add((MyClass)(m.invoke(null)));
}
}
Then I call it like that:
MyClass.populate((Collection<MyClass>)(Collection<?>)collection, MyClassDescendant.class, 3);
This code works, but it's ugly. What I actually wanted to achieve would look like this:
MyClassDescendant.populate(collection, 3);
If it wasn't a static method, I'd just use this.getClass(). I know that MyClass.class would work for static method, but I don't want class for MyClass, but for specific MyClassDescendant (there are few descendant types).
Is there any way to get class object without having its instance or class name?
Since you are in a static context you'll have to duplicate some code, but you can do delegation.
public class MyClassDescendant extends MyClass {
public static void populate(Collection<MyClass> coll, int count) {
MyClass.populate(coll, MyClassDescendant.class, count);
}
}
Now you can call
MyClassDescendant.populate(collection, 3);
Try restructuring your method in this way:
public static <T extends Base> void populate(Collection<T> coll, int num) throws Exception{
for (T item : coll) {
Method m;
m = item.getClass().getMethod("getRandom");
coll.add((T)(m.invoke(null)));
}
}
With regards to one the comments, you can also use the template method design pattern to utilize inheritance for your getRandom() method by making it abstract and calling it within your populate method.
If get random is a static method couldn't you just call it?
public interface MyClassInterface {
MyClass getRandom();
}
public abstract class MyClass implements MyClassInterface {
public static void populate(Collection<MyClass> coll, int num) {
for (int i = 0; i < num; i++) {
coll.add((MyClass)MyClassDescendant.getRandom());
}
}
}
public class MyClassDescendant extends MyClass {
public MyClass getRandom() {
// implementation of getRandom
}
}
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();
}