Why can't the second class get variable data from third class? - java

I am having a problem with passing of variables between classes.
The problem that I am having is that the second class is not obtaining the variable data from the third class after first class sets the value to teh variables in third class.
The way in which I would like it to work is that I have one class (classA) where it obtains the value from the user and calls the set method is the third class to set the value to the variable, second class (classB) will be used get the value using the get method in the third class and the third class (ClassC) is where get and set methods resides.
ClassA method coding:
//method for 'add' button functionality
public void btnAddActionPerformed(java.awt.event.ActionEvent evt)
{
ArrayList<UserInfo> userobjList = new ArrayList<>();
//calling data field revelant text fields
int EmpNumber = Integer.parseInt(txtEmpNum.getText());
String EmpAccessType = txtAccessType.getText();
//creating the object to parse data to userinfo class
UserInfo user = new UserInfo(EmpNumber, EmpAccessType);
//setting the data to varibales in userinfo class
user.setEmpNumber(EmpNumber);
user.setEmpAccessType(EmpAccessType);
//adds the object to the arraylist
userobjList.add(user);
//creates the object to use the method for adding employee to system
AddEmpFunction addUser = new AddEmpFunction();
addUser.test();
}
This class obtains user information and sets the data in the third class
ClassB method for adding user to system coding:
//variables
int EmpNumber;
String AccessTypes;
//creation of object to be used throughout
UserInfo user = new UserInfo(EmpNumber, AccessTypes);
public void AddNewEmpLogin()
{
try
{
//SQL string command to be executed to add user login details
String addNewUserLogin = "insert into userLoginData(Username, accessType) values ("
+ user.getEmpNum() + ","
+ quotate(user.getEmpAccessType()) + ")";
//create the statement that will be used
Statement stmt=conn.createStatement();
//executes the addNewUser statement
stmt.executeUpdate(addNewUserLogin);
}
catch (Exception e)
{
//exception error message is shown
JOptionPane.showMessageDialog(null, "Error adding new User's details \n " + e, "Database Error", JOptionPane.ERROR_MESSAGE);
}
}
This class is where the data will be obtained from third class and then stored in MySQL.
ClassC is where the get and set methods are:
private int EmpNumber;
private String EmpAccessType;
//constructor
public UserInfo(int EmpNumber, String EmpAccessType)
{
this.EmpNumber = EmpNumber;
this.EmpAccessType = EmpAccessType;
}
public int getEmpNum()
{
return EmpNumber;
}
public void setEmpNum(int EmpNum)
{
this.EmpNumber = EmpNum;
}
public String getEmpAccessType()
{
return EmpAccessType;
}
public void setEmpAccessType(String EmpAccessType)
{
this.EmpAccessType = EmpAccessType;
}
The data is passing perfectly well from classA to classC but the data returned in classB whcih calls it up form classC displays null for the string and 0 for the integer.
Please could someone please explain where my problem is and how I can fix this. I have read a lot about get and set methods and there is no actualy example for what I am trying to achieve.
Any help will be much appreciated. :)

Because you have two different instances of the third class. You're doing this in one place (variable names changed to illustrate):
UserInfo userA = new UserInfo();
userA.setEmpNumber(EmpNumber);
userA.setEmpAccessType(EmpAccessType);
And then this in another:
UserInfo userB = new UserInfo();
userB.getEmpNumber();
userB.getEmpAccessType();
So you set data on one object, and then try to get that data from another object. But you can't, because no data was ever set on that object.
As an analogy, consider two identical cars. Same make, same model, came off the same production line. You are putting gas into one car, then trying to drive the other one. But you can't. Because it doesn't have any gas in it.
You need to use the same instance of the object:
UserInfo user = new UserInfo();
user.setEmpNumber(EmpNumber);
user.setEmpAccessType(EmpAccessType);
// ...
user.getEmpNumber();
user.getEmpAccessType();
If your second class needs a valid instance of your third class in order to perform its task, then it should require that as a constructor parameter. So when the first class holds that user variable and then creates an instance of the second class, it passes the user variable to that instance. So there's only one user.
(Additionally, as a side note, you don't need to pass the values to the constructor and use the setters. One or the other is fine. A value only needs to be set once.)

int EmpNumber;
String AccessTypes;
//creation of object to be used throughout
UserInfo user = new UserInfo(EmpNumber, AccessTypes);
You set up new user with no field filled.
And then you
+ user.getEmpNum() + ","
+ quotate(user.getEmpAccessType()) + ")";
from your empty user so it returns 0 and null respectively.
Pass your user from classA to classB first?

Your class B does not seem to receive data from class A.
Class C, UserInfo is a data store object (POJO) but the instance user that is created in class A is never passed to class B in your sample code.
As a matter of fact, class B seems to create its own instance of UserInfo with empty values.
So, to keep this short: pass the user object from class A to B, for example by using AddEmpLogin( UserInfo user ).
Next, read a solid introduction to object-oriented programming.

Related

How to reuse a method, but adding more features to the second one?

I have a method addUser() in Class Register that works as a regular form, asking the user of the system things like "firstName", "lastName", "username", and "password".
class Register {
void addUser() {
try {
System.out.print("First Name:\n> ");
String firstName = userInput.nextLine();
(...)
}
}
Only once the user is registered and logged in, they can add new customers using a method in the Class Customer, that performs just as addUser(), but adding more fields, like "address" and "email".
class Customer {
/*At the moment I'm redoing all over again just because it works.
and because I didn't know how to implement in any other way.*/
void addCustomer() {
try {
System.out.print("First Name:\n> ");
String firstName = userInput.nextLine();
System.out.print("Address:\n> ");
String address = userInput.nextLine();
(...)
How can I reuse the addUser() method in the Customer class using the fact that the user is logged in as a condition? Thanks in advance for your time.
Firstly I'd suggest you move the addUser method out of both Register and Customer - that way you have some guarantee that the method is not tied to any particular use case and thus will be reusable.
Then you're going to need to create mechanism for both calling contexts (Customer and Register) to interface with the addUser method. For this you could use some kind of data object which they exchange, and then once they get it back they pull out the data they want, or you can let both them implement an interface that the addUser method can be passed with which it will and back what it captures.
I don't feel using inheritance is a good enabler of reuse in this case. Inheritance is something which must be done carefully as it can also increase dependencies. It is important to adhere to the idea that when using inheritance the 2 types being inheritance should actually have some inheritance relationship - I don't think this is the case here.
So then the Register user can call this addUser method and the Customer class can call this addUser method and then add the extra fields it includes.
You can use a static boolean value set to false (e.g: isLoggedIn). If the user logs in successfully, change it to true. Then call this method in the Customer class (create Register object) only if the isLoggedIn variable equals true
I'll rephrase your question as "How can I make my code less repetitive and easier to maintain through reuse?"
The solution in that case is to create a reusable function that takes care of the repeated task of printing a prompt and reading in from the keyboard:
public class Console {
public static String prompt(String field) {
System.out.print(field + ":\n> ");
return userInput.nextLine();
}
}
Then you can simplify your other functions:
void addUser(){
try {
String firstName = Console.prompt("First Name");
(...)
}
}
void addCustomer(){
try {
String firstName = Console.prompt("First Name");
String address = Console.prompt("Address");
(...)
}
}
Other forms of reuse are object composition and inheritance, but I feel that they are not necessary based on the example code that you gave.

Java - Method declared but cannot reference it

I am kind of new to Java, although I've programmed in other procedural langauages for 25 years. So, I'm trying to teach myself Java. Trying to write some silly program consisting of two files: a Class called "Customer", and a main program called "Silly4".
I'm pretending to implement a credit card system for a bank type company (even though the majority of my experience was in defense contracting). I figure this would be a good teaching example for me.
Trying to build a credit card data structure called "Customer" such that (for the time being) it can accomodate 1000 customers. In the main program "Silly4", I instantiate this Customer class as "cust2", and then from there I attempt to work with "cust2". I try to retrieve customer number 5's (j=5) credit card balance. So far, so good.
Then from there I attempt to declare in the class Customer another method (for future use) which I arbitrarily call "bal44", and then I attempt to reference it in the main program Silly4 as " ball44(5541);".
So I compile class Customer, then compile program Silly4, and I'm getting a compile error "java:52: error: cannot find symbol" for the reference to method "bal44(5541)" in main program "Silly4". I'm confused. I've declared and successfully compiled the class Customer with "bal44" in there, but Java is telling me it can't find it. I'm confused.
Please excuse all the extraneous println's, I use them to see how the program is moving along.
Here is class Customer:
// Data Structure for credit card database
public class Customer {
private String name;
private int accountNo;
private double balance;
private boolean Overdue;
// Getters, setters, constructor...
public void setName( String new_name )
{ name = new_name; }
public void setAccount( int new_account )
{ accountNo = new_account; }
public void setBalance( double new_bal )
{ System.out.println( " Start proc setBalance ");
balance = new_bal;
System.out.println( " Finish proc setBalance ");
}
public double getBalance()
{ System.out.println( " Start proc getBalance ");
System.out.println( " proc getBalance , balance= " + balance + " end print");
return balance;
// how to specify which element of array[1000] ? balance I want ?
// System.out.println( " Finish proc getBalance ");
}
// Add new customer to credit card system
// (note - index in array Customer[i] is worry of main program
//
public void addCustomer( String name2, int account2, double bal2 )
{ name = name2;
accountNo = account2;
balance = bal2;
}
public void bal44 ( int account3 )
{ accountNo = account3; }
// Constructor
Customer ()
{ name = "John Smith";
accountNo = 1005;
balance = 125.43;
Overdue = false; }
// see page 1032 Liang for definition complex Object and get-Procs for it
}
Here is main program/class Silly4:
class Silly4
{
// Program for credit card database
public static void main(String[] args)
{
double bal2, bal3;
int i; // loop counter
int j;
bal2 = 151.47;
bal3 = 5.0; // just initialize
// And then you can create an array of it:
System.out.println("** Program Silly4 Running **");
Customer[] cust2 = new Customer[1000];
System.out.println("** Array cust2 instantiated **");
for(i=0; i<=999; ++i)
{
cust2[i] = new Customer();
}
System.out.println("** Array2 cust2 Obj initialized **");
// try to code this eventually - cust2.balance = 151.47 ;
//
j = 5; // customer no. 5
cust2[j].setBalance( bal2 );
bal3 = cust2[j].getBalance() ;
System.out.println("** Balance Customer " + j + " is " + bal3);
// Add a new customer
// comment out - addCustomer( "Steve Jones", 5541, 1.0 );
bal44( 5541 ); // test out declaring new method "bal44"
System.out.println("** End of Silly4 **");
}
}
You basically answered yourself in the first sentence of your query. Java is not a purely procedural language, it's an object-oriented language.
That means that when you declare methods, they are not just scoped functions. A method declared in a class is not similar to a function declared in an included file in C. It's something that can be only called from the scope of an object of the enclosing class. In other words, you don't have a function named bal44. You have a method bal44 of class Customer, which means that you need to ask an object fo class Customer to execute it for you, similar to how you call setBalance().
EDIT: As another comment mentions, what might be confusing you more is that whenever you use a method name without qualifiers, Java treats it as a shortcut of asking this (the current object) to execute the method, so technically, method(args) is a shortcut for this.method(args). Therefore, whenever you are within the scope of a single class, a class's methods will behave almost as traditional functions.
When you call
bal44( 5541 );
Without any object, Java assumes it as a "this" object and searches for that method in Silly4 not in Customer class. Call that method from Silly4 like you are calling other method of customer class.
e.g.
cust2[j]. bal44( 5541 ); or something like that.
Read more about "this" here https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
P.S. A bonus point to note here is that static method's like main method do not have this reference available to them. So, technically here it is searching for a class-level(static) method in Silly4 rather than instance method. :)
See, here is the problem : You are using the bal44(5541), but you made that method non static, meaning you need to make an object of your class (Customer) and then say for example
Customer customer = new Customer()
customer.bal(5541);
If you want to call that method without making an object of its class, simply put the keyword "static" in the method's header. public static void bal44(int num)
Further explanation : Since you are from a procedural language, recall the main difference is the usage of objects. An object is something that has several traits, or attributes, and actions or behaviors. For example a car, its attributes are its color, speed, etc. and its main action/behavior is drive. Attributes are variables, and Behaviors/Actions are methods. e.g.
car.drive();
car.setColor("red");
I hope that helped? If you don't understand you can PM me or respond here and I'll explain in further detail

How do I minimize object creation in this particular situation?

While implementing a database structure, my goal is to provide easy access to player data.
So, I have created the User class, which holds a Json instance and exposes the methods to take specific information from it.
public class User {
private Json data;
public User(OfflinePlayer player) {
File path = new File(player.getUniqueId() + ".json");
data = new Json(path);
}
public boolean isPremium() {
return data.getBoolean("premium");
}
}
The problem is that I have to create a new instance every time I need to know something about the same player from different parts of my code. That's very expensive!
So, is there a design pattern for this particular situation?
This is a simple cache. If you are using ORM such as hibernate, you could use second level cache for this.
You could also have unique user identifier (UUID id) as a key, with user data as a value in Map.
So, when you get request for user data, you first see if you have user with this uuid in cache(Map) and return data if you do.
If you don't have it, then go in database and fetch data.
Try creating a Map like this:
User user = null;
Map<UUID, User> usermap = new HashMap<>;
//before creating new user instance check if its present in Map
if(usermap.containskey(id){
//get user from Map
user = usermap.get(id);
else{
//not in map so create new User
user = new User(id);
usermap.put(id,user);
}
//use user object
But please be careful to destroy usermap instance or object containing it once it is not required. You can also so several modification with limiting size etc.

Java: Code Understanding

I'm new to JAVA, but I know Objective-C. I have to write a server side Custom Code and I'm having trouble with the code below:
/**
* This example will show a user how to write a custom code method
* with two parameters that updates the specified object in their schema
* when given a unique ID and a `year` field on which to update.
*/
public class UpdateObject implements CustomCodeMethod {
#Override
public String getMethodName() {
return "CRUD_Update";
}
#Override
public List<String> getParams() {
return Arrays.asList("car_ID","year");
}
#Override
public ResponseToProcess execute(ProcessedAPIRequest request, SDKServiceProvider serviceProvider) {
String carID = "";
String year = "";
LoggerService logger = serviceProvider.getLoggerService(UpdateObject.class);
logger.debug(request.getBody());
Map<String, String> errMap = new HashMap<String, String>();
/* The following try/catch block shows how to properly fetch parameters for PUT/POST operations
* from the JSON request body
*/
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(request.getBody());
JSONObject jsonObject = (JSONObject) obj;
// Fetch the values passed in by the user from the body of JSON
carID = (String) jsonObject.get("car_ID");
year = (String) jsonObject.get("year");
//Q1: This is assigning the values to fields in the fetched Object?
} catch (ParseException pe) {
logger.error(pe.getMessage(), pe);
return Util.badRequestResponse(errMap, pe.getMessage());
}
if (Util.hasNulls(year, carID)){
return Util.badRequestResponse(errMap);
}
//Q2: Is this creating a new HashMap? If so, why is there a need?
Map<String, SMValue> feedback = new HashMap<String, SMValue>();
//Q3: This is taking the key "updated year" and assigning a value (year)? Why?
feedback.put("updated year", new SMInt(Long.parseLong(year)));
DataService ds = serviceProvider.getDataService();
List<SMUpdate> update = new ArrayList<SMUpdate>();
/* Create the changes in the form of an Update that you'd like to apply to the object
* In this case I want to make changes to year by overriding existing values with user input
*/
update.add(new SMSet("year", new SMInt(Long.parseLong(year))));
SMObject result;
try {
// Remember that the primary key in this car schema is `car_id`
//Q4: If the Object is updated earlier with update.add... What is the code below doing?
result = ds.updateObject("car", new SMString(carID), update);
//Q5: What's the need for the code below?
feedback.put("updated object", result);
} catch (InvalidSchemaException ise) {
return Util.internalErrorResponse("invalid_schema", ise, errMap); // http 500 - internal server error
} catch (DatastoreException dse) {
return Util.internalErrorResponse("datastore_exception", dse, errMap); // http 500 - internal server error
}
return new ResponseToProcess(HttpURLConnection.HTTP_OK, feedback);
}
}
Q1: Code below is assigning the values to fields in the fetched Object?
carID = (String) jsonObject.get("car_ID");
year = (String) jsonObject.get("year");
Q2: Is this creating a new HashMap? If so, why is there a need?
Map<String, SMValue> feedback = new HashMap<String, SMValue>();
Q3: This is taking the key "updated year" and assigning a value (year)? Why?
feedback.put("updated year", new SMInt(Long.parseLong(year)));
Q4: If the Object is updated earlier with update.add... What is the code below doing?
result = ds.updateObject("car", new SMString(carID), update);
Q5: What's the code below doing?
feedback.put("updated object", result);
Original Code
SMSet
SMInt
Q1: They read from the fetched JSON object and stores the values of the fields car_ID and year in two local variables with the same names.
Q2: Yes. The feedback seems to be a map that will be sent back to the client as JSON
Q3: It stores the value read into the local variable 'year' (as described earlier) in the newly created hashmap 'feedback'
Q4: Not sure, I assume the ds object is some sort of database. If so it looks like it takes the updated values stored in the hashmap 'update' and pushes it to the database.
Q5: It stores the "result" object under the key "updated object" in the feedback hashmap.
Hope this helps :)
Q1
No, it does not appear to be setting a class member variable, but rather a variable local to the execute() method. As soon as the method returns, those local vars are cleaned up by the GC. Well, not really, but they are now subject to GC, but that's getting really technical.
Q2
Yes, you are creating a HashMap and putting it's reference into a Map. Map is an interface, and it's good practice in Java to reference thing like this. This way you are not tying your code to a specific implementation. I believe in Objective-C they are know as Prototypes???
Q3
I am not sure why they are doing this. I assume somewhere in the code the feedback Map is used, and that value is plucked back out. Think of Maps as an NSDictionary. It looks like "year" is a String, so they use Long.parseLong() to convert it. Not sure what SMInt is...from the name it looks like a custom class that represents a "small int"???
Q4
I don't know what DataService is, but I have to guess its some sort of service the reads/write data??? From the method, I am guessing its calling the service to update the values you just changed.
Q5
Again, feedback is a Map...it's putting result in the "updated object" key of that map.

Retrieving multiple values from an arraylist

I have saved values retrieved from a database in java to an arraylist.
I have used a class to save the data to the array list as shown below.
ArrayList<NewSms> details = new ArrayList<NewSms>();
try{
Statement query = conn.createStatement();
ResultSet result = query.executeQuery("Select `senderAddress,message,linkid from sdp_smsincoming where status=0 AND smsServiceActivationNumber =1234 ");`
while(result.next()){
String address = result.getString("senderAddress");
String message = result.getString("message");
String linkid = result.getString("linkid");
NewSms smsdetails = new NewSms();
smsdetails.set_address(address);
smsdetails.set_message(message);
smsdetails.set_linkid(linkid);
details.add(smsdetails);;
}
}
However i now want to retrieve the values individually per row,from another class in the program.How can i do this?By individually i mean getting the address,message and linkid per row in the arraylist.
However i now want to retrieve the values individually per row,from another class in the program.How can i do this?
You just access each NewSms in the list. To access one by index, you could use:
NewSms sms = details.get(2); // Or whatever
// Now access the properties of sms
Or to access each of them in turn, use an enhanced for loop:
for (NewSms sms : details) {
// Now access the properties of sms
}
Note that to comply with Java naming conventions, your NewSms class should have methods such as getAddress, setAddress - not set_address.
Also note that you need to close your result set / statement / connection - if you're using Java 7, you can use a try-with-resources statement; otherwise you should use finally blocks.
EDIT: If your problem is actually just returning the list, that's easy:
public List<NewSms> loadSmsDetails() {
// Code as before...
return details;
}
Then just call it from your other class:
// Where repository is a reference to an instance of the class containing the above method
List<NewSms> allDetails = repository.loadSmsDetails();
for(NewSms smsdetails:details){
String address = smsdetails.get_address();
String message = smsdetails.get_message();
String linkId = smsdetails.get_linkid();
}
However i now want to retrieve the values individually per row,from
another class in the program
You need to pass the arraylist to the another class and iterate over it there to get the individual elements. The idea is to use a common araylist - to store the values from the resultset and in another class to iterate through them.

Categories