How do Java classes get information from the Entry class? - java

So lets say that in my entry point class (i.e the class which runs when the program starts (which has the public static void main(String args[]) function). In that class I have this variable:
private ArrayList<String> myData=new ArrayList<String>();
This class instantiates another class, which needs to have access to the myData member of the entry point class. How can it retrieve this arraylist?
Edit: To clarify, in the main() method I could do this:
SomeOtherClass myClass=new SomeOtherClass();
and then I could do:
myClass.someMethod();
however, in the myClass object, how could I perform a method/retrieve something from the entry class, which instantiated the myClass object?

It sounds like your entry point is still static when it calls some other class, but your ArrayList is a member of an instance of it. You need to move out of the static world and into instances.
I'd refactor your main method into a private construtor, and put in a new main() which launches it as a new instance.
Note that this code is very rough, but it should serve to illustrate what you need to do.
public class EntryPoint {
private ArrayList<String> myData=new ArrayList<String>();
public static void main( String[] args ) {
EntryPoint ep = new EntryPoint();
ep.init();
}
private void init() {
// Populate myData perhaps?
SomeOtherClass myClass=new SomeOtherClass();
myClass.someMethod( this );
}
public List<String> getMyData() {
return myData;
}
}
public class SomeOtherClass {
public void someMethod( EntryPoint entry ) {
List<String> data = entry.getMyData();
// do stuff with data..!
}
}

The best way to give the class you instantiate access to myData would be to pass it into the constructor when it is created.
Then, in your constructor, you can save the ArrayList into a member variable of the class.
For example, your object constructor will look like:
private ArrayList<String> myData;
public YourObjConstructor(ArrayList<String> data){
myData = data;
}

The class containing main() is just an ordinary class. In your case, you'd have to make myData public and possibly static (or, of course, add an accessor). Just like you'd do with any other class.
You could also pass an Entry object to the other class, like this:
public static void main(String[] args) {
Entry entry = new Entry();
SomeOtherClass myClass=new SomeOtherClass(entry);
// continue as before
}

Related

Question about the mechanism of the ArrayList

Basically, when I passed arguments in Java, I knew it was passing only value.
However, the following code shows that the add method executed on SubClass's SubMethod affects ArrayList of MainClass.
MainClass.java
public class MainClass{
public satatic void main(String[] args){
List list = new ArrayList<>();
SubClass subClass = new SubClass(list);
subClass.subMethod();
System.out.println(list) // Why added value???
}
}
SubClass.java
public class SubClass{
private List list;
public SubClass(List list){
this.list = list;
}
public void subMethod(){
list.add(1);
list.add(2);
}
}
When I did the same thing with a HashMap's put, there was no effect on the HashMap of the MainClass.
I would like to know why only ArrayList is causing these results and what is happening inside Java.
Update
The code for the hashmap version is as follows:
MainClass.java
public class MainClass{
public satatic void main(String[] args){
Map map = new HashMap<>();
SubClass subClass = new SubClass(map );
subClass.subMethod();
System.out.println(map) // Not putting value
}
}
SubClass.java
public class SubClass{
private Map map;
public SubClass(Map map){
this.map= map;
}
public void subMethod(){
map = someGenerationHashMap(arg1, arg2);
}
}
It's not about ArrayList. Any object you pass as an argument can be modified. What is passed by value is the address of the object, not the object itself.
In the Map version, you are not making any operation that could modify it. In the list version instead, you are making an add.
Make sure not to confuse objects with primitives. For example, make sure not to confuse int with Integer.

Run method from different class with variables from current class

I need to run a method from a different class but I want to use the variables for the method from the class I am going to call the method from. I don't want to pass parameters in as there are too many variables for the method and also, it would ruin my code for the original class.
An example of my code is as follows -
Class to run method from
variable1;
variable2;
variable3;
otherClass OC = new OtherClass();
otherClass.method();
and the so called 'otherClass' method (the class with the method), is for example
variable1;
variable2;
variable3;
public void method()
{
//DOES STUFF WITH variable1 variable2 and variable3
}
what i want it to do is run the method with the variables from the class in which I am calling the method, i.e. the class for the code i posted first. Is there any way to do this?
As OldProgrammer said, a proper solution is to use a container to encapsulate all variables your methods need.
An example:
public class ContainerClassExample {
private static class Container {
Object variable1, variable2, variable3;
public Container(Object variable1, Object variable2, Object variable3) {
this.variable1 = variable1;
this.variable2 = variable2;
this.variable3 = variable3;
}
}
public static void main(String[] argv) {
Container aContainer = new Container("a", "b", "c");
methodA(aContainer);
System.exit(0);
}
public static void methodA(Container input) {
// Do something with variable1, variable2, and variable3
}
}
Greater is the number of the input parameters, more I suggest you to use the builder pattern to create your container.

How can i access a static variable by a class name in Java?

I have many classes which have the same static attribute (staticAttr) and i have another class which accepts the class name and accesses its staticAttr of the class name specified.
How can i do this. Please help me!
Thanks.
EDIT:
public class Group_name1 extends Activity implements View.OnClickListener,
{
public static Group_name1 staticVar;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.group_name1);
staticVar = this;
}
}
public class Group_name2 extends Activity implements View.OnClickListener,
{
public static Group_name2 staticVar;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.group_name2);
staticVar = this;
}
}
Now my problem is to have an access to the static variable of these classes in another class by just giving a class name string. Now the class should can be used to get the staticVar which contains the object.
Currently, i have created seperate classes for every class mentioned above to refer to the staticVar. But i feel its redundant and bad style of programming because every class i write for refering to the above classes does the same function. The only thing that changes is the Class name reference
Group_name1 grpActivity;
Group_name2 grpActivity;
These are my current implementations. But i want to just use the class name to refer the static variable
class GroupNameListener1 extends Thread
{
Group_name1 grpActivity;
public void run()
{
grpActivity = Group_name1.staticVar;
/*
do something
*/
}
}
class GroupNameListener2 extends Thread
{
Group_name2 grpActivity;
public void run()
{
grpActivity = Group_name2.staticVar;
/*
do something
*/
}
}
Like this :
ClassWithStaticVariable.VariableName
if you have
class A {
public static String a = "test"
}
then you can access it like this :
class B {
public void test() {
System.out.println(A.a);
}
}
If I am understanding you correctly you have something like
class A {
public static String str = "test"
}
and in you code you have a method like
void methodA (A someObj) {
in this method you can access the static variable
as
A.str
or
someObj.str
What you have is very bad design. Short of reflection there is no way to solve this generically as you designed it.
I believe what you are trying to do is attaching meta data to your classes. A very simple way to do that would be to keep a global map holding the data (and work with the class instead of its name):
public class MyClassMetaData {
private final static Map<Class<?>, String> dataMap = new HashMap<>();
static {
dataMap.put(MyClassA.class, "TestA"); // one method of initialization
dataMap.put(MyClass2.class, "Case2");
// one line per class...
}
private MyClassMetaData() {
}
public static String getMetaData(Class<?> theClass) {
return dataMap.get(theClass);
}
}
But you need to remember to add a line that puts the data into the map into the static block when you add another class.
If you need to initialize data dynamically, access to the map may need to be synchronized.

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.

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

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();
}

Categories