Pass a class method to another class method - java

Say I have the following class
class Application {
public Application() {...}
public void doSomething(final String logs) {
final String[] lines = logs.split("\\n");
for (final String line: lines) {
// Pass the line to every single checkForProp# item and do something with the response
}
}
private Optional<Action> checkForProp1(final String line) {
// Check if line has certain thing
// If so return an Action
}
// More of these "checks" here
}
Let's say every single response, would be added to a queue, and then returned something is done on that queue.
So instead of I calling each method manually, I want to have maybe an array of checker methods, and automatically loop through them, pass in the line, and add the response to a queue.
Can this be achieved?

You can implement your Action as interface:
public interface Action{
public void fireAction();
}
Those classes which implement Action will then override the method defined in the interface, such as checking a String.
Add the instances of Action to the list and you loop them accordingly.
Example:
for(Action a : actions)
a.fireAction();

If i understood your question correctly then following code may be help you.
import java.lang.reflect.Method;
public class AClass {
private void aMethod(){
System.out.println(" in a");
}
private void bMethod(){
System.out.println(" in b");
}
private void cMethod(){
System.out.println(" in c");
}
private void dMethod(){
System.out.println(" in d");
}
//50 more methods.
//method call the rest
public void callAll() {
Method[] methods = this.getClass().getDeclaredMethods();
try{
for (Method m : methods) {
if (m.getName().endsWith("Method")) {
//do stuff..
m.invoke(this,null);
}
}
}catch(Exception e){
}
}
public static void main(String[] args) {
AClass a=new AClass();
a.callAll();
}
}
Here Java Reflection is used.

Related

Java State Pattern with different implementation resulting in a difficult to understand error

Why is this java code not working.
abstract class Actor {
Actor a = new HappyActor();
abstract void act();
void change() { a = new SadActor(); }
void go() { a.act(); }
}
class HappyActor extends Actor {
public void act() {
System.out.println( ":)" );
}
}
class SadActor extends Actor {
public void act() {
System.out.println( ":(" );
}
}
public class TransmogrifyMe {
public static void main( String[] args ) {
Actor s = new HappyActor();
s.go(); // Prints ":)"
s.change();
s.go(); // Prints ":("
}
}
It was my modification to the popular State pattern but not working unfortunately:
The assignment statement in the abstract class is called at the beginning of every constructor of a class inheriting from it. So the assignment statement tries to create an object of a derived class. i.e Actor a = new HappyActor() is called when the constructor of class HappyActor is called which results in a never ending loop of constructor call. Is this really what is happening?
The working version looks like the code below:
abstract class Actor {
abstract void act();
}
class HappyActor extends Actor {
public void act() {
System.out.println( ":)" );
}
}
class SadActor extends Actor {
public void act() {
System.out.println( ":(" );
}
}
class Stage {
Actor a = new HappyActor();
void change() { a = new SadActor(); }
void go() { a.act(); }
}
public class Transmogrify {
public static void main( String[] args ) {
Stage s = new Stage();
s.go(); // Prints ":)"
s.change();
s.go(); // Prints ":("
}
}
The resulting error message in the first code is an unending loop of these two lines:
at Actor.<init>(TransmogrifyMe.java:6)
at HappyActor.<init>(TransmogrifyMe.java:12)
Is it possible to implement this kind of state change using inheritance. I found this in Bruce Eckel's book Thinking in Java In contrast you can't decide to inherit differently at run-time; that must be completely determined at compile-time
Get rid of the class variable. Your methods should look like this:
State doSomething() {
// do something, e.g. println.
return new NextState();
// or return this to stay in the current state.
}
and they are then used like this:
state = state.doSomething();
i.e. you return the next state.
e.g.
class HappyState implements State {
public State change() {
return new SadState();
}
}
Consider what happens when you attempt to create your first HappyActor. The default ctor needs first to create the guts of the Actor, and the first thing that does is tries to construct a HappyActor. Boom, infinite recursion.
In the second code sample, which is indeed correct, Actor is the "State" of Stage. (Maybe Actor, being so self contained and independent from Stage, is more like a Strategy, but at this complexity level the difference is meaningless.)
Do you want to do something else?
So I did it this way according to Anony-Mousse 's suggestion:
// StateChange.java
// Implementing the state pattern using inheritance
interface State {
public State change();
public void print();
}
class SadState implements State {
public State change() {
return new SadState();
}
public void print() {
System.out.println( ":(" );
}
}
class HappyState implements State {
public State change() {
return new SadState();
}
public void print() {
System.out.println( ":)" );
}
}
public class StateChange {
public static void main( String[] args ) {
State h = new HappyState();
h.print(); // prints :)
h = h.change();
h.print(); // prints :(
h = h.change();
h.print(); // prints :)
}
}
That's the best I could do!

How to use same object between diffrent methods

I am novice to Java coding.
I wanted to know how to pass the same object between different methods?
Ex:
Class A
{
//Declaring an object say
Object obj;
public void Method1()
{
//Here i want to use some method of obj
obj=new Object();
obj.Metod1();
}
public void Method2()
{
//Here i want to use another method of obj
obj.Metod2();
}
}
class B
{
A aObj=new A();
aObj.Method1();
aObj.Method2();
}
From the above code, how can i use the object created in Method1() can be used in Method2?
This is my actual code:
public class UtilityFunctions
{
File fileName;
public static FileWriter fwObj;
public static BufferedWriter bwObj;
Logger App_log;
UtilityFunctions()
{
fileName=new File(System.getProperty("user.dir")+"\\src\\TempFile.html");
Logger App_log=Logger.getLogger(UtilityFunctions.class);
try
{
if(!fileName.exists())
fileName.createNewFile();
this.fwObj=new FileWriter(fileName);
this.bwObj=new BufferedWriter(fwObj);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void writeHeader()
{
try
{
this.bwObj.append("<html><body><table border='1' style='widht:300px'><tbody><tr><th>Date</th><th>Position</th><th>Site</th></tr>");
this.bwObj.flush();
// this.bwObj.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void writeFooter()
{
try
{
this.bwObj.append("</html></body></table></tbody>");
this.bwObj.flush();
bwObj.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void writeReport(String strstrPositionName)
{
DateFormat format=new SimpleDateFormat("MM/dd/yyyy");
Date date=new Date();
String strCurrentDate=format.format(date);
try
{
String strFormattedString="<tr><td>"+strCurrentDate+"</td><td>"+strstrPositionName+"</td><td>SomeSite</td></tr>";
App_log.info("Printing the Line as: "+strFormattedString);
this.bwObj.append(strFormattedString);
this.bwObj.flush();
// bwObj.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
I would like to call above methods like
Class TempClass
{
public static void main(String args[] args)
{
UtilityFunctions obj=new UtilityFunctions();
obj.writeHeader();
obj.writeReport("Message1");
obj.writeReport("Message2");
// I may add many write Report statements here.
obj.writeFooter();
}
}
The problem i see here, writeHeader is working fine, but at execution of writeReport I am getting NullPointer Exception. How to overcome this?
java.lang.NullPointerException
at UtilityFunctions.writeReport(UtilityFunctions.java:71)
at TempClass.writeDetailedReport etc.........
Here is how you can pass the object frome one method to another
public void method1()
{
Object objToBePassed=new Object();
method2(objToBePassed);
}
public void method2(Object passedObject)
{
// your logic
}
You should create your objects within constructor of the class, and then you can easly use this object. for example:
class YourClass {
private Object obj;
public YourClass() { //constructor
obj = new Object();
}
public void method() {
//your logic
}
To sum up, If you create fields of your class in constructor you don't worry about null pointers and all of class methods have access to those objects. If you want to use private field outside your class, for example in method from other class you should use getter method and pass object in argument:
public void otherMethod(Object obj)
First declare your object as a field for your class:
class MyClass
{
private Object obj;
//...Rest of class goes here
}
Initialize the object in your constructor so that it is not null when you want to access it.
public MyClass()
{
this.obj = new Object();
}
Now you can access it from your two methods as you wish.
public method1()
{
this.obj.doSomething();
}
public method2()
{
this.obj.doSomethingElse();
}
All in all, it can look something like this:
class MyClass
{
private Object obj;
public MyClass()
{
this.obj = new Object();
}
public method1()
{
this.obj.doSomething();
}
public method2()
{
this.obj.doSomethingElse();
}
}
Now if you want to actually pass an object from one method to another but don't want it to be accessible to any other methods, you can make it a parameter like this:
public method1(Object obj)
{
obj.doSomething()
}
And then you can call the method from somewhere else passing specific instances of the object type.
public method2()
{
Object obj1 = new Object();
Object obj2 = new Object();
this.method1(obj1); //All actions in method1 will be done to obj1
this.method1(obj2); //All actions in method1 will be done to obj2
}
Passing parameters is especially useful if you want to call a single method several times, but have it act on different inputs.

How to read and write to variables of an abstract class

Put simply, I have an abstract class containing several variables and methods. Other classes extend this abstract class, yet when I try to read the private variable in the abstract class by calling getter methods inside the abstract class, it returns null as the value of the variable.
public class JavaApplication {
public static void main(String[] args) {
NewClass1 n1 = new NewClass1();
NewClass2 n2 = new NewClass2();
n1.setVar("hello");
n2.print();
}
}
public class NewClass1 {
public String firstWord;
public void setVar(String var) {
firstWord = var;
}
public String getVar () {
return firstWord;
}
}
public class NewClass2 extends NewClass1{
public void print() {
System.out.println(makeCall());
}
public String makeCall() {
return getVar();
}
}
Still prints out null.
Until the String is initialized, it will be null. You should probably have a constructor in the abstract class to set it.
public abstract class Command
{
String firstWord; // = null
protected Command(){}
protected Command( String w )
{
firstWord = w;
}
//...
}
public class Open extends Command
{
public Open()
{
this( "your text" );
}
public Open( String w )
{
super( w );
}
// ...
}
If you need to modify the firstWord string everytime execute() is called then it may not be necessary to use a constructor with a String parameter (I added a default constructor above). However, if you do it this way then either
You must make sure setFirstWord() is called before getFirstWord(), or,
Handle the case when getFirstWord() returns null. This could be by simply using a default value (maybe determined by each subclass) or something else, like failing to execute.
As I do not know all the details of your implementation I cannot tell you further information.

Method as parameter with signature contract?

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.

Java PropertyChangeListener

I'm trying to figure out how to listen to a property change in another class. Below is my code:
ClassWithProperty has the property I want to listen to:
public class ClassWithProperty {
private PropertyChangeSupport changes = new PropertyChangeSupport(this);
private int usersOnline;
public int getUsersOnline() {
return usersOnline;
}
public ClassWithProperty() {
usersOnline = 0;
while (usersOnline<10) {
changes.firePropertyChange("usersOnline", usersOnline, usersOnline++);
}
}
public void addPropertyChangeListener(
PropertyChangeListener l) {
changes.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(
PropertyChangeListener l) {
changes.removePropertyChangeListener(l);
}
}
Main is where i need to know about the property change:
public class Main {
private static ClassWithProperty test;
public static void main(String[] args) {
test = new ClassWithProperty();
test.addPropertyChangeListener(listen());
}
private static PropertyChangeListener listen() {
System.out.println(test.getUsersOnline());
return null;
}
}
I have the event fired only the last time (usersOnline=10).
I'm new to Java and tried to find a solution, but to no avail.
The code:
private static PropertyChangeListener listen() {
System.out.println(test.getUsersOnline());
return null;
}
returns null which means "no object", which in turn means that test.addPropertyChangeListener(listen()) is effectively test.addPropertyChangeListener(null), which won't register anything.
You must pass a valid instance of a PropertyChangeListener to the addPropertyChangeListener() method.
Edit
I suggest you read the Java tutorial's chapter about PropertyChangeListeners:
http://download.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html
Another problem of your code is that you call firePropertyChange() in the constructor of ClassWithProperty. But at that time, no listener can possibly be registered, so it does not have any effect. Any call to addPropertyChangeListener() happens after you have fired the events.
Here is your code modified so that it should work (haven't tested it though...):
public class ClassWithProperty {
private PropertyChangeSupport changes = new PropertyChangeSupport(this);
private int usersOnline = 0;
public ClassWithProperty() {
}
public void setupOnlineUsers()
{
while (usersOnline < 10) {
changes.firePropertyChange("usersOnline", usersOnline, ++usersOnline);
}
}
public int getUsersOnline() {
return usersOnline;
}
public void addPropertyChangeListener(PropertyChangeListener l) {
changes.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
changes.removePropertyChangeListener(l);
}
}
public class MainListener implements PropertyChangeListener {
private ClassWithProperty test;
public MainListener() {
test = new ClassWithProperty();
test.addPropertyChangeListener(this);
test.setupOnlineUsers();
}
public void propertyChange(PropertyChangeEvent evt) {
System.out.println(test.getUsersOnline());
}
public static void main(String[] args) {
new MainListener(); // do everything in the constructor
}
}
What I do is put a method in the ClassWithProperty class:
public PropertyChangeSupport getPropertyChangeSupport() {
return changes;
}
Then, register for property change events in the constructor of your Main() class:
private void initializeListeners() {
test.getPropertyChangeSupport().addPropertyChangeListener((PropertyChangeEvent event) -> {
if (event.getPropertyName().equals("usersOnline")) {
String passedEventData = (String) event.getNewData();
}
});
}
This make it so you are not repeating the code in your ClassWithProperty with methods that are already in the PropertyChangeSupport class.
when you need to fire an event in your ClassWithProperty class, do:
changes.firePropertyChange("usersOnline", oldValue, newValue);
One notable feature of this method is that, if the
event.getOldValue() and the event.getNewValue()
are equal, the event will not fire. If you want to fire repeated events with the same information, use null in the oldValue field;
The firePropertyChange() method only passes int, boolean and Object. So if you are not passing an int or boolean, you need to cast the value that was passed in the event on the receiving end.
Your method here:
public ClassWithProperty() {
usersOnline = 0;
while (usersOnline<10) {
changes.firePropertyChange("usersOnline", usersOnline, usersOnline++);
usersOnline++;
}
}
has a while loop that will continuously loop and block the thread. My limited knowledge of property change listeners is that they listen for changes to a bound property, here the usersOnLine variable, meaning the property change should only fire if this number changes (likely within in any setUserOnLine, addUserOnLine, removeUserOnLine and similar methods). For more on bound properties, please look here: Bound Properties

Categories

Resources