Any tips on getting around the pass-by-value issue? - java

In the code below I have a classic Java pass-by-value issue (written in processing; setup() == main).
void setup()
{
A a = new A();
a.makeTheB(a.b);
System.out.println(a.b); //Returns null
}
class A
{
B b;
public void makeTheB(B tempB)
{
tempB = new B();
}
}
class B
{
float x; //not used
}
Anyone have any clever tricks they use to assign a new object to a reference passed as a parameter?
I can describe my intent if needed, but I would love a generalized answer if one exists.
EDIT: Looks like I need to describe my intent.
I'm using the Composite pattern to create a recursive hierarchy of objects. I have an object outside that hierarchy that I would like to reference one of the objects within the hierarchy. I would like to pass that object though the composite, Chain of Responsibility style, and then have that object reference whichever object took responsibility for it.
I can find a way to achieve this though return values I'm sure, but being able to assign the parameter I passed down the hierarchy would sure be nice if there's any cleaver way to do it.

You can try returning the object of B that you create in class A4
Illustrated below.
public class A {
B b;
public B makeTheB(B tempB) {
tempB = new B();
return tempB;
}
}
public class B {
float x; //not used
}
public class Test {
public static void main(String[] args) {
A a = new A();
B b = a.makeTheB(a.b);
System.out.println(b); //Returns nu
}
}
Output: B#7852e922

You can do this, but perhaps you need to provide a better description of what you want to achieve.
void setup()
{
A a = new A();
a.makeTheB(a);
System.out.println(a.b);
}
class A implements Consumer<B>
{
B b;
public void accept(B b) {
this.b = b;
}
/**
* Create a B, and give it to a Consumer which knows where it needs to be stored.
*/
public void makeTheB(Consumer<B> consumer)
{
consumer.accept(new B());
}
}
class B
{
float x; //not used
}

Related

Accessing a particular instance of class inside the same class in java

I have a java code with the structure that is shown below:
public class x{
public static void main(string[] args)
{
ysample1 = new y(m)
ysample2 = new y(l)
....
}
}
public class y{
private int m_m
public y(int m)
{
m_m = m
}
public void control()
{
h h1 = new h(ysample2)
}
}
At some point when I want to call method control for ysample1 I may need to access ysample2 object.How can I define instance of class y global, so I can access ysample2 inside the control method in class y?
Does anyone know how can I fix this? Thanks.
You can't do what you want to do the way you wrote it.
I think you need to ridefine "control()" method like this:
public void control(Y ysample)
{
h h1 = new h(ysample)
}
So now you need to have an "ysample" as parameter and you can do from your main
control(ysample2);
and you will have what i understood from you question. If you need something else please comment.

Simple pass of variable to new class, then output in Java

I've seen this question asked in several ways, but the code is usually specific to the user, and I get lost a little. If I'm missing a nice clear and simple explanation, I'm sorry! I just need to understand this concept, and I've gotten lost on the repeats that I've seen. So I've simplified my own problem as much as I possibly can, to get at the root of the issue.
The goal is to have a main class that I ask for variables, and then have those user-inputted variables assessed by a method in a separate class, with a message returned depending on what the variables are.
import java.io.*;
public class MainClass {
public static void main(String[] args) {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
String A;
String B;
try {
System.out.println("Is A present?");
A = reader.readLine();
System.out.println("Is B present?");
B = reader.readLine();
Assess test = new Assess();
} catch (IOException e){
System.out.println("Error reading from user");
}
}
}
And the method I'm trying to use is:
public class Assess extends MainClass {
public static void main(String[] args) {
String A = MainClass.A;
String B = MainClass.B;
if ((A.compareToIgnoreCase("yes")==0) &&
((B.compareToIgnoreCase("yes")==0) | (B.compareToIgnoreCase("maybe")==0)))
{
System.out.println("Success!");
}
else {
System.out.println ("Failure");
}
}
}
I recognize that I'm not properly asking for the output, but I can't even get there and figure out what the heck I'm doing there until I get the thing to compile at all, and I can't do THAT until I figure out how to properly pass values between classes. I know there's fancy ways of doing it, such as with arrays. I'm looking for the conceptually simplest way of sending a variable inputted from inside one class to another class; I need to understand the basic concept here, and I know this is super elementary but I'm just being dumb, and reading what might be duplicate questions hasn't helped.
I know how to do it if the variable is static and declared globally at the beginning, but not how to send it from within the subclass (I know it's impossible to send directly from the subclass...right? I have to set it somehow, and then pull that set value into the other class).
In order to pass variables to an object you have either two options
Constructor - will pass parameter when creating the object
Mutator method - will pass parameters when you call the method
For example in your Main class:
Assess assess = new Assess(A, B);
Or:
Assess assess = new Assess();
assess.setA(A);
assess.setB(B);
In your Assess class you have to add a constructor method
public Assess(String A, String B)
Or setter methods
public void setA(String A)
public void setB(String B)
Also, Assess class should not extend the main class and contain a static main method, it has nothing to do with the main class.
Below there is a code example!
Assess.java
public class Assess {
private a;
private b;
public Assess(String a, String b) {
this.a = a;
this.b = b;
}
public boolean check() {
if ((A.compareToIgnoreCase("yes")==0) &&
((B.compareToIgnoreCase("yes")==0) ||
(B.compareToIgnoreCase("maybe")==0)))
{
System.out.println("Success!");
return true;
} else {
System.out.println ("Failure");
return false;
}
MainClass .java
public class MainClass {
public static void main(String[] args) {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
String A;
String B;
try {
System.out.println("Is A present?");
A = reader.readLine();
System.out.println("Is B present?");
B = reader.readLine();
Assess test = new Assess(A, B);
boolean isBothPresent = test.check();
// ................
} catch (IOException e){
System.out.println("Error reading from user");
}
}
I think what you're looking for are method parameters.
In a method definition, you define the method name and the parameters it takes. If you have a method assess that takes a string and returns an integer, for example, you would write:
public int assess(String valueToAssess)
and follow it with code to do whatever you wanted with valueToAssess to determine what integer you wanted to return. When you had decided that i was the int to return, you would put the statement
return i;
into the method; that terminates the method and returns that value to the caller.
The caller obtains the string to be assesed, then calls the method and passes in that string. So it's more of a push than a pull, if you see what I mean.
...
String a = reader.readLine();
int answer = assess(a);
System.out.println("I've decided the answer is " + answer);
Is that what you're looking for?
A subclass will have access to the public members of the superclass. If you want to access a member using {class}.{member} (i.e. MainClass.A) it needs to be statically declared outside of a method.
public class MainClass {
public static String A;
public static String B;
...
}
public class Subclass {
public static void main(String[] args) {
// You can access MainClass.A and MainClass.B here
}
}
Likely a better option is to create a class that has these two Strings as objects that can be manipulated then passed in to the Assess class
public class MainClass {
public String A;
public String B;
public static void main(String[] args) {
// Manipulate A, B, assign values, etc.
Assess assessObject = new Assess(A, B);
if (assessObject.isValidInput()) {
System.out.println("Success!");
} else {
System.out.println("Success!");
}
}
}
public class Assess {
String response1;
String response2;
public Assess (String A, String B) {
response1 = A;
response2 = B;
}
public boolean isValidInput() {
// Put your success/fail logic here
return (response1.compareToIgnoreCase("yes") == 0);
}
}
First you don't need inheritance. Have one class your main class contain main take the main out of Assess class. Create a constructor or setter methods to set the variables in the Assess class.
For instance.
public class MainClass
{
public static void main(String[] Args)
{
Assess ns = new Assess( );
ns.setterMethod(variable to set);
}
}
I'm not 100% sure of your problem, but it sounds like you just need to access variables that exist in one class from a subclass. There are several ways...
You can make them public static variables and reference them as you show in your Assess class. However, they are in the wrong location in MainClass use
public static String A, B;
You can make those variables either public or protected in the parent class (MainClass in your example). Public is NOT recommended as you would not know who or what modified them. You would reference these from the sub-class as if present in the sub-class.
public String A, B; // Bad practice, who modified these?
protected String A, B;
The method that might elicit the least debate is to make them private members and use "accessors" (getters and setters). This makes them accessible programmatically which lets you set breakpoints to catch the culprit that is modifying them, and also let you implement many patterns, such as observer, etc., so that modification of these can invoke services as needed. If "A" were the path to a log file, changing its value could also cause the old log to close and the new one to be opened - just by changing the name of the file.
private String A, B;
public setA(String newValue) {
A = newValue;
}
public String getA() {
return A;
}
BUT ...
Your question says "send to the subclass", but confounded by your knowing how to do this using global variables. I would say that the simplest way is to provide the values with the constructor, effectively injecting the values.
There are other ways, however, your example shows the assessment performed by the constructor. If your Assess class had a separate method to perform the assessment, you would just call that with the variables as arguments.
Your example is confusing since both classes have main methods and the child class does the assessing - I would think you would want the opposite - Have MainClass extend Assess, making "MainClass an Assess'or", let main assign the Strings to Assess' values (or pass them as arguments) to the parent class' "assess" method ("super" added for clarity):
super.setA(local_a);
super.setB(local_b);
super.assess();
or
super.assess(A, B);

Testing functions in class which expects string in constructor using Mockito

I have the following class and want to write unit test for it. Below is the class for full reference. X is POJO
public class StatusTable {
private P tableData;
private Q tableDefinition;
public StatusTable(final List<X> xList,
final A a,
final B b)
throws URISyntaxException {
setTableDefinition(a, b);
setTableData(xList, b, a);
}
private void setTableDefinition(final A a,
final B b) {
//some code
}
public void setTableData(final List<X> xList,
final B b, final A a)
throws URISyntaxException {
for (X sfm : xList) {
//some code
}
}
}
Being new to unit testing, I have very minimal idea of how to test but here is a thought. Please correct me wherever incorrect.
public class StatusTableTest {
private StatusTable statusTable;
#Mock
private A mockA;
#Mock
private B mockB;
#Mock
private X mockX;
public void setUp() {
stub(mockX.getSomeValue()).toReturn(?); //want to return any string
stub(mockX.getSomeAnotherValue()).toReturn(?); //want to return any integer
//Similarly mock other functions retuning
this.statusTable = new StatusTable(xList, mockA, mockB,);
}
public void setTableDefinitionTest() {
//test the code
}
}
I have a few doubts:
a) Am I doing it correctly? Should the X be mocked?
b) Is there anyString() kind of functionality in Mockito or should I use something else?
a) It is hard to tell without actual code. You can mock individual X values or whole List of X.
b) Your end result is based on expected values, so you should not return anyString(), but some specific String. So you can verify that your code behaves correctly for this particular String. I.e. assert that table contains single cell with "abc" text if passed list with one X returning "abc".
Depending on what you want to mock.
You can mock any call to your class and return any value or spy on an existing class and overload a call with your mocked call.
For instance
mockedX = Mockito.mock(X.class);
Mockito.when(mockedX.someFunction("1")).thenReturn(someAnswer);
or:
X x = new X();
spiedX = Mockito.spy(x);
Mockito.answer(some answer).when(spiedX).someFunction("1");
Remember ... the mocked class will return what you are mocking.
If you create a mock like this:
Mockito.when(mockedX.someFunction(Mockito.anyString())).thenReturn("A");
then on every call someFunction() will return "A".

How to call a method from class inside another class

My main java code is like that:
package Javathesis;
//import... etc
//...
public class Javathesis; // My main class
{
public static void // There are a lot of these classes here
//...
//...
class x
{
String a;
String b;
x(String a, String b)
{
this.a = a;
this.b = b;
}
}
public void getAllDataDB1
{
ArrayList<ArrayList<x>> cells = new ArrayList<>();
while(resTablesData1.next())
{
ArrayList<CellValue> row = new ArrayList<>();
for (int k=0; k<colCount ; k++) {
String colName = rsmd.getColumnName(i);
Object o = resTablesData1.getObject(colName);
row.add(new x(rsmd.getColumnType(),o.toString());
}
cells.add(row);
}
public static void main(String[] args)
{
connectToDB1();
// i want to call an instance of class "x" HERE!!!
}
}
How can i call class x in public static void main? Am i doing something wrong? I already test the way i know
Class class = new Class();
class.x(String a, String b);
but i receive errors. Can somebody help me to fix this?
Thanks in advance.
Since x is an inner class it need an outer class instance to obtain a reference:
Class x = new Javathesis().new x(a, b);
In addition the semi-colon needs to be removed from the class declaration
Methods in x can be invoked using the reference created
Java Naming conventions show that classes start with an uppercase letter. Also its good to give the class a more meaningful name than a single letter name
There are multiple problems with this code:
Class class = new Class();
class.x(String a, String b);
You cannot name a variable 'class', it is a reserved word. Also, x is a class - you cannot just call it, you need to instantiate it.
Also, why would you instantiate a Class - which is a class encapsulating knowledge about Java class?
Something like that might work:
Javathesis thesis = new Javathesis();
Javathesis.x thesis_x = new thesis.x("a","b);
Also, please, start class names with the capital letter - it is a convention in Java.
You should create an instance of your inner class
YourInnerClass inner = new YourOuterClass().new YourInnerClass();
and then call a method on it
inner.doMyStuff();
To call a class method without instantiating an object from that class, the method must be declared as static, and then invoked from wherever you want using the class name dot method parentheses arguments.
public class x {
//constructor, etc
public static int add(int x,y) {
return x+y;
}
}
//make the call from somewhere else
int y = x.add(4,5);

Java: common code for all constructors?

It seems to me constructors can share the same code, for example in:
public class Foo {
private int foo;
{foo = 5;}
public Foo(){}
public Foo(int v){this.foo = v;}
public int getFoo(){return foo;}
}
The code "foo=5;" is called for both constructors.
It seems to me you can not, but I want to make sure. It not possible to create such common code that use parameters ?
eg, something like:
public class Foo {
private int foo;
(int m){foo = m*5;}
public Foo(int m){}
public Foo(int v,int m){this.foo = v;}
public int getFoo(){return foo;}
}
To my understanding, the only way is to create a private void init(int m) to be called by all constructors ?
ps: I call {foo = 5;} "common code", but I guess this feature has another official name ?
EDITS (1):
The term I was looking for is initializer block
This question is not the same as asking if a constructor can also call another
constructor. Because when using an initializer block, the code is called AUTOMATICALLY, ie. without risk to call a constructor and forget to call it
My comment about using "void init" was not good, indeed in this case calling another constructor is better.
In short, my question: can an initializer block takes parameters ? Which would be kind of the same as forcing some parameters on all constructors to be implemented.
EDITS (2):
I now wonder if the only way to achieve what I am asking is to use inheritance to force the use of a specific constructor.
You can call your constructors from other constructors by calling this(), and matching the parameter list.
Say i have:
Foo(int a, int b) {
// some code..
}
but i want to also call:
Foo(int a, int b, int c) {
// some other code
}
I would say this:
Foo(int a, int b) {
this(a, b, 0);
// Whatever other code you want in this constructor.
}
You need to understand the way how Java creates objects!Assume the you have
class A{
private String b = "b";
private static String a = "a";
{
b = "b2";
}
static{
a = "a2";
}
public A()
{
b = "b3";
}
}
So the idea is that when you create an object
new A();
The first
private static String a = "a";
After
static{
a = "a2";
}
After
private String b = "b";
After
{
b = "b2";
}
And only after
public A()
{
b = "b3";
}
But be careful the priorities of static variables and static blocks are the same. And the priorities of normal variables and blocks are again the same. So if you put the next code
static{
a = "a2";
}
and after
private static String a = "a";
you will have that the code in the block is ignored, because you use the variable before declaration! And the same for normal variables!

Categories

Resources