At the startup, I am creating a string according to the database type in class A. Then I want to inject that string value to class B after the setBitAndSqlExpression() function is called. After the injection I want to use that variable in Class B. Class B is executed if the user makes a request after run time init.
Note that they are in different packages. I cannot pass them via the constructor.
class A { //code first enters here
public String BITAND_SQL_EXPRESSION;
public void setBitAndSqlExpression() {
try {
String driverName = dataSource.getConnection().getMetaData().getDriverName();
if (driverName.contains("PostgreSQL")) {
BITAND_SQL_EXPRESSION = "%s" + "::INTEGER" + " & %s = %s";
} else {
BITAND_SQL_EXPRESSION = "BITAND (%s,%s) = %s";
}
} catch (Exception e) {
LOGGER.warn("Driver cannot be found. Setting operations will not work correctly.");
}
}
}
class B { //enters here if only user makes a request after class A creation.
public String BITAND_SQL_EXPRESSION; // want to use the value at class A
public B(
...//codes and constructors.
}
Is a factory method possible for you ?
It would be in the package of the B class :
public interface IB {
methodA();
methodB();
}
class B implements IB{ //enters here if only user makes a request after class A creation.
public String BITAND_SQL_EXPRESSION; // want to use the value at class A
public B(
...//codes and constructors.
}
public final class BFactory {
public static IB create(String sqlExpression) {
return new B(sqlExpression);
}
}
Then in the package of class A you could call this factory
BFactory.create(BITAND_SQL_EXPRESSION);
A would depend of an interface and not the B implementation.
I am writing a testing framework using Gauge.
I want some initilization logic performed in one class, and the steps logic to reuse it, like this:
public class A {
protected String property = "";
#BeforeSpec
public void init(){
property = "hello";
}
}
public class B extends A {
#Step("...")
public void verifyProperty() {
assertEquals(property, "hello");
}
}
I can't seem to be able to achieve this. When performing the steps, the "property" is always null.
Placing the #BeforeSpec in class B and calling super.init() works, but I would like to avoid having this call in every test class that extends A.
Has anyone encountered and solved such an issue?
Try to use a static variable:
public class A {
public static String property = "";
#BeforeSpec
public void init(){
property = "hello";
}
}
public class B {
#Step("...")
public void verifyProperty() {
assertEquals(A.property, "hello");
}
}
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);
I have code like below sample. in that I am telling the class_name to get package name. instead of this method, i need another logic to get the package name withoud telling the class_name directly.
package smk.jsf.bean;
public class test {
public static void main(String[] args) {
System.out.println(test.class.getPackage().getName());
//Is there any option like "this.class.getPackage().getName();" bz. i don't want use class_name direclty
}
}
Output : smk.jsf.bean
Thanks to everyone.
Finally I got solution below
package smk.jsf.bean;
public class test {
public static void main(String[] args) {
String className = new Object(){}.getClass().getPackage().getName();
System.out.println(className);
}
Not sure it will suit you but try sun.reflect.Reflection.getCallerClass(). This class is present in JDK.
It will return a Class instance of method caller. Then just getPackage(). It is really dangerous stuff but it lets you not to use the class name directly.
Example usage - create a method String getPackageName() which will get caller class and return package name and call it from main.
Or you can throw any throwable, catch it and parse that throwable's stack trace to get the target package name (really sick way).
I have two approaches.
You can add a field public static final PACKAGE_INFO = "%package%"; to each file. Then traverse your source directory, read the line with the package package someName and replace the %package%
Use a dynamic approach at runtime. I wrote a little example program.
public class PackageExample {
public static void main(String[] args) throws ClassNotFoundException {
Example e = new Example();
System.out.println(e.getPackage());
}
}
interface MetaInformation {
public String getPackage() throws ClassNotFoundException;
}
class InformationGatherer implements MetaInformation {
public String getPackage() throws ClassNotFoundException {
StackTraceElement[] ste = new Exception().getStackTrace();
if (ste.length < 2)
throw new IllegalStateException("StackTrace to small to determine package!");
String clazz = ste[1].getClassName();
Class<?> c = Class.forName(clazz);
String package_ = "";
Package p = c.getPackage();
if (p != null)
package_ = c.getPackage().getName();
return package_;
}
}
class Example implements MetaInformation {
private InformationGatherer ig = new InformationGatherer();
public String getPackage() throws ClassNotFoundException {
return ig.getPackage();
}
}
Not sure if this helps but you can use reflection
http://docs.oracle.com/javase/tutorial/reflect/
Similar question :
See Can you find all classes in a package using reflection?
If it's a static method.No.
You cannot use this in a static context,since main is static method.
If it is not a static method,
String name = this.getClass().getPackage().getName();
So i'm having a bit of a problem trying to compare two strings declared in the Main class. I've messed around with it and i really can't get it to work! The problem is in the if() statement where i compare the variables...
public class Main {
public String oldContent = "";
public String newContent = "";
public static void main(String[] args) throws InterruptedException {
Main downloadPage = new Main();
downloadPage.downloadPage();
oldContent = newContent;
for (;;) {
downloadPage.downloadPage();
if (!oldContent.equals(newContent)) { // Problem
System.out.println("updated!");
break;
}
Thread.currentThread().sleep(3000);
}
}
private void downloadPage() {
// Code to download a page and put the content in newContent.
}
}
the variables are instance members, whereas the for happens in a static method.
try moving the actual function to an instance method (not static), or conversely make the data members static as well.
You may use name of the object you have created (downloadPage ) to access to the parameters:
in the main finction use following instead of parameter names only:
downloadPage.oldContent
downloadPage.newContent
The variables are inside the Main object:
public static void main(String[] args) throws InterruptedException {
Main downloadPage = new Main();
downloadPage.downloadPage(); // Access them like you accessed the method
downloadPage.oldContent = downloadPage.newContent;
for (;;) {
downloadPage.downloadPage();
if (!downloadPage.oldContent.equals(downloadPage.newContent)) {
System.out.println("updated!");
break;
}
Thread.currentThread().sleep(3000);
}
}
Do consider using getters and setters instead of exposing the fields.
See non static/ static variable error