I am trying to test Spring Dependency Injection functionality but running into issues when trying to retrieve value of an instance variable using getter methods of Spring Bean class. Getting null value of a previously set instance variable.
My Main Class
public class Main {
public static void main(String ... args) {
ApplicationContext context = new ClassPathXmlApplicationContext("BeanFactory.xml");
IBackup dataWriterObj = (IBackup) context.getBean("writeBackupHDFS");
backup backup = new backup();
backup.setNickName("Abbey");
String result = dataWriterObj.read("Ankur", "Bahre");
System.out.println(result);
}
}
Bean Class
public class backup implements IBackup {
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String read(String firstName, String lastName) {
String Name = "My Name is " + firstName + " " + lastName + " and my nickName is " + getNickName();
return Name;
}
}
Interface
public interface IBackup {
public String read(String firstName, String lastName);
}
BeanFactory.xml
<bean id="writeBackupHDFS" class="test.backup"/>
Expected Output- My Name is Ankur Bahre and my nickName is Abbey
Actual Output- My Name is Ankur Bahre and my nickName is null
Can anyone suggest what is it that I am missing ?
Thanks
Use dataWriterObj.setNickName("Abbey") instead of backup.setNickName("Abbey").
Because below code has no relation with dataWriterObj object.
backup backup = new backup();
backup.setNickName("Abbey");
Edit:
Create another Class with name
public class Name {
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
}
Update backup class with the above change
public class backup implements IBackup {
#Autowired
Name nameObj;
public void setNameObj(Name nameObj) {
this.nameObj = nameObj;
}
public String read(String firstName, String lastName) {
String Name = "My Name is " + firstName + " " + lastName + " and my nickName is " + nameObj.getNickName();
return Name;
}
}
Add it to conf file BeanFactory.xml:
<bean id="writeBackupHDFS" class="springboot.rest.backup">
<property name="nameObj" ref="nameBean"/>
</bean>
<bean id="nameBean" class="springboot.rest.Name"/>
Now update main method with below code
ApplicationContext context = new ClassPathXmlApplicationContext("BeanFactory.xml");
IBackup dataWriterObj = (IBackup) context.getBean("writeBackupHDFS");
Name nameBean = (Name) context.getBean("nameBean");
// backup backup = new backup();
nameBean.setNickName("Abbey");
String result = dataWriterObj.read("Ankur", "Bahre");
System.out.println(result);
Related
I am trying to learn static factory methods and their advantages over constructors
but my code is throwing an error that final String name is not assigned a value(name might no be initialized)
public class Main {
public final String name;
private final String email;
private final String country;
public Main(String name, String email, String country) {
this.name = name;
this.email = email;
this.country = country;
}
public Main() {}
static Main createName(String name, String email) {
return new Main(name, email, "Argentina");
}
public static void main(String[] args) {
Main obj = new Main();
createName("vipin", "vipin.com");
System.out.println("This is name: " + obj.name + "\n" + "This is email address: " +
obj.email + "\n" + "This is country: " + obj.country);
}
}
Change:
Main obj = new Main();
createName("vipin", "vipin.com");
to:
Main obj = createName("vipin", "vipin.com");
and forget the no-parameter constructor which do not initialise correctly the fields.
An instance variable is initialized by its default value unless it is final when the object is instantiated. If you initialize it out of one of its constructors, it cannot be initialized in the constructor(s). So, advisedly, final instance variables should be initialized in constructors.
I'm working on my code, to call some constructors from classes I created.
I'm sorry if my question is easy, but I tried to search everywhere and didn't figure out the answer.
On the other hand, all my classes are working well without any error.
When I need to call the constructor from the main class, it's giving me an error.
non-static variable this cannot be referred from a static context.
I will just post the first class I'm calling and having an error.
public class Test1 {
static int nextPers = 1;
public class Person{
private int persID;
private String persName;
private String email;
Person(int persID, String persName, String email){
persID = nextPers;
nextPers++;
this.persName = persName;
this.email = email;
}
public static void main(String [] args){
Person per = new Person(1 , "Raphael" , "meh#hotmail.com");
}
}
I cannot continue, the program is asking me to put static variables, and I cannot figure my error because when I write static before the variable, it's creating another error.
Your class Person is an inner class of Test1.
Move it to its own file or add the static keyword, like so:
public class Test1 {
public static class Person {
// your fields
}
}
I suggest reading up this other answer for a detailed explanation.
You should have a static counter for ID and not give it into constructor
public class Person {
private int persID;
private String persName;
private String email;
private static int nextPers = 0;
Person(String persName, String email){
this.persID = nextPers;
nextPers++;
this.persName = persName;
this.email = email;
}
public static void main(String [] args){
Person per = new Person("P0" , "p0#hotmail.com");
System.out.println(per.persID + " " + per.email + " " + per.persName);
per = new Person("P1" , "p1#hotmail.com");
System.out.println(per.persID + " " + per.email + " " + per.persName);
per = new Person("P2" , "p2#hotmail.com");
System.out.println(per.persID + " " + per.email + " " + per.persName);
}
}
nextPers must be a static class member, like
public class Person {
private static int nextPers = 0;
private int persID;
private String persName;
private String email;
Person(String persName, String email) {
this.persID = nextPers++;
this.persName = persName;
this.email = email;
}
}
(In your original code you are assigning nextPers to the persId argument, which I assume isn't what you really want, as it masks your instance variable with the same name.)
Place your Person class outside and you do not need to persId into your constructor.
package com.test;
class Person{
private int persID;
private String persName;
private String email;
Person( String persName, String email){
this.persID = Test.nextPers;// Whenever your constructor is invoked it will assign nextPers to persId
this.persName = persName;
this.email = email;
Test.nextPers++;// finally increment here
}
public int getPersID()
{
return persID;
}
public void setPersID( int persID )
{
this.persID = persID;
}
public String getPersName()
{
return persName;
}
public void setPersName( String persName )
{
this.persName = persName;
}
public String getEmail()
{
return email;
}
public void setEmail( String email )
{
this.email = email;
}
#Override
public String toString()
{
return "Person [persID=" + persID + ", persName=" + persName + ", email=" + email + "]";
}
}
public class Test
{
static int nextPers = 1;
public static void main( String[] args )
{
Person person1 = new Person("Raphael" , "meh#hotmail.com");
System.out.println( person1 );
Person person2 = new Person("Man" , "man#hotmail.com");
System.out.println( person2 );
}
}
Output
Person [persID=1, persName=Raphael, email=meh#hotmail.com]
Person [persID=2, persName=Man, email=man#hotmail.com]
I am just starting to get into Object Oriented Programming in Java. I am curious about what the difference (if any) is between the 2 pieces of code below.
public class BuyAHouseInc
{
// Instance variables
private String firstName;
private String surname;
private String address;
private int budget;
// method to set the first name in the object
public void setFirstName(String firstName)
{
this.firstName = firstName; // stores the first name
}
// method to retrieve the first name from the object
public String getFirstName()
{
return firstName; // return value of first name to caller
}
// method to set the surname in the object
public void setSurname(String surname)
{
this.surname = surname; // stores the surname
}
// method to retrieve the surname from the object
public String getSurname()
{
return surname; // return the value of surname to caller
}
// method to set the address in the object
public void setAddress(String address)
{
this.address = address; // stores the address
}
// method to retrieve the address from the object
public String getAddress()
{
return address; // return the value of address to caller
}
// method to set the budget in the object
public void setBudget(int budget)
{
this.budget = budget; // store the budget
}
// method to retrieve the budget from the object
public int getBudget()
{
return budget; // return the value of address to caller
}
}
This is the 2nd piece of code;
public class BuyAHouseInc
{
public void displayClient(String firstName, String surname, String address, int budget)
{
System.out.println("Client Name: " + firstName + " " + surname);
System.out.println("Address: " + address);
System.out.println("Budget: " + "€" + budget);
}
}
I prefer the 2nd piece of code here because its clearer to understand but I have been reading a lot on methods and objects and I can't figure out what the actual differences are. Are set and get methods secure ways of entering values?
Let's start with what you think is the simpler code:
public class BuyAHouseInc
{
public void displayClient(String firstName, String surname, String address, int budget)
{
System.out.println("Client Name: " + firstName + " " + surname);
System.out.println("Address: " + address);
System.out.println("Budget: " + "€" + budget);
}
}
We could instantiate this class and use it like so:
public static void main(String[] args) {
BuyAHouseInc buyAHouseInc = new BuyAHouseInc();
buyAHouseInc.displayClient("jane", "doe", "123 main street", 100000);
}
The effect of this main method is to display the information on your screen. That's everything instances of this class can do. You can't share the information, or reuse it.
The first piece of code you show lets you create an object with fields that store data that you can reuse. The getters and setters are written so you can access those fields to use elsewhere in your program.
We can also add the displayClient method to this class, like so:
public class BuyAHouseInc {
private String firstName;
private String surname;
private String address;
private int budget;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
...
public void displayClient() {
System.out.println("Client Name: " + this.firstName + " " + this.surname);
System.out.println("Address: " + this.address);
System.out.println("Budget: " + "€" + this.budget);
}
}
So then I might be able to write a program like this:
public class Solution {
public static void main(String[] args) {
BuyAHouseInc jane = new BuyAHouseInc("jane", "doe", "123 main street", 100000);
BuyAHouseInc john = new BuyAHouseInc("john", "doe", "123 main street", 50000);
System.out.println("The following clients can afford to buy a house");
if (canAffordTheHouse(jane)) {
jane.displayClient();
}
if (canAffordTheHouse(john)) {
john.displayClient();
}
}
public static boolean canAffordTheHouse(BuyAHouseInc client) {
return client.getBudget() > 50000;
}
}
If you're asking about getter / setter vs direct access, then there are many advantages of getter / setter over direct access.
Basically:
It's more secure as variable implementations should be kept private
and non accessible by public sources.
It allows for additional functionality in the get / set call and
allowing different behavior for whom is getting / setting.
It allows for different access levels (public, protected, etc.)
It is, however, the exact same speed as accessing directly.
Here is another answer that shows what I said in more detail.
You could combine the blocks of code
public class BuyAHouseInc
{
// Instance variables
private String firstName;
private String surname;
private String address;
private int budget;
public void displayClient()
{
System.out.println("Client Name: " + this.firstName + " " + this.surname);
System.out.println("Address: " + this.address);
System.out.println("Budget: " + "€" + this.budget);
}
// method to set the first name in the object
public void setFirstName(String firstName)
{
this.firstName = firstName; // stores the first name
}
// method to retrieve the first name from the object
public String getFirstName()
{
return firstName; // return value of first name to caller
}
// method to set the surname in the object
public void setSurname(String surname)
{
this.surname = surname; // stores the surname
}
// method to retrieve the surname from the object
public String getSurname()
{
return surname; // return the value of surname to caller
}
// method to set the address in the object
public void setAddress(String address)
{
this.address = address; // stores the address
}
// method to retrieve the address from the object
public String getAddress()
{
return address; // return the value of address to caller
}
// method to set the budget in the object
public void setBudget(int budget)
{
this.budget = budget; // store the budget
}
// method to retrieve the budget from the object
public int getBudget()
{
return budget; // return the value of address to caller
}
}
Alternatively, you could pass a whole object of BuyAHouseInc into the display function.
public void displayClient(BuyAHouseInc b)
{
System.out.println("Client Name: " + b.getFirstName()+ " " + b.getSurname());
System.out.println("Address: " + b.getAddress());
System.out.println("Budget: " + "€" + b.getBudget());
}
public void displayClient(String firstName, String surname, String address, int budget)
{
//........
}
is simply another method. Enclosed in { and } defines what it does when a call to displayClient() method is called. displayClient() requires 3 arguments before it can perform it's task. The arguments are what's inside the () in public void displayClient(String firstName, String surname, String address, int budget). The 2nd piece of code can be put within the public class BuyAHouse block or { }. Your setters() and getters() are also similar to displayClient() but has fewer arguments.
What's inside { } of public class BuyAHouse are members or methods. These methods has access to the class variables
private String firstName;
private String surname;
private String address;
private int budget;
That's why on most of the syntax of setters(), you can see that it's setting/assigning/storing (whatever you like) values to your class variables. So basically set() methods are used to modify the value of the variables firstname, surname,address and budget
getters() are used to return the value of the variables.
For instance,
String name; //this has no string value yet
//function definition - you tell what you want this method to do
public void setMyName(String yourName){
name = yourName; //you store the value of yourName to name
}
//method call
setMyName("whatever name you like"); // whatever name you like will be passed to the yourName variable
This is no homework.Its an exercise I came across in a book.
Build a class named Name which represents the name of a person.The class should have fields that represent first name ,last name ,and fathersname.
The class should have these methods :
public Name (String fn,String f_n,String ln)
/* initializes the fields of an object with the values fn,f_n and m.
fn means first name
ln means last name
f_n means fathersname btw. */
public String getNormalOrder(); //returns the name of the person in the normal order : first name,fathers name,last name.
public String getReverseOrder(); //returns the name of the person in the reverse order : last name,fathers name,first name.
public boolean compare (String fn,String f_n,String ln); // Returns true if the first name is the same with fn,fathers name is the same with f_n, last name with ln.If the opposite happens it returns false.
Build a program named TestName which tests the methods of the class Firstname.
My solution
public class Name {
String fn;
String f_n;
String ln;
public Name(String initialfn, String initialf_n, String initialln) {
fn = initialfn;
f_n = initialf_n;
ln = initialln;
}
public String getNormalOrder() {
return fn + " " + f_n +
" " + ln;
}
public String getReverseOrder() {
return ln + ", " + f_n +
" " + fn + " ";
}
}
How about the third method which is comparing? Also how do I test the class?
For a flexible solution:
public enum NameMember {
FIRSTNAME, SECONDNAME, FATHERSNAME;
}
The Name class:
public class Name {
private final String firstName;
private final String secondName;
private final String fathersName;
public Name(String firstName, String secondName, String fathersName) {
this.firstName = firstName;
this.secondName = secondName;
this.fathersName = fathersName;
}
public String getName(NameMember member1, NameMember member2, NameMember member3) {
StringBuilder sb = new StringBuilder();
return sb.append(getMember(member1)).append(" ")
.append(getMember(member2)).append(" ")
.append(getMember(member3)).toString();
}
public String getMember(NameMember member) {
switch (member) {
case FIRSTNAME:
return firstName;
case SECONDNAME:
return secondName;
case FATHERSNAME:
return fathersName;
default:
return null;
}
}
#Override
public String toString() {
return getName(NameMember.FIRSTNAME, NameMember.SECONDNAME, NameMember.FATHERSNAME);
}
}
A NameComparator (flexible) class:
import java.util.Comparator;
public class NameComparator implements Comparator<Name> {
private NameMember nameMember;
public NameComparator(NameMember nameMember) {
this.nameMember = nameMember;
}
#Override
public int compare(Name name1, Name name2) {
return name1.getMember(nameMember).compareTo(name2.getMember(nameMember));
}
}
And the main class (test drive):
public static void main(String args[]) {
List<Name> names = new ArrayList<>();
names.add(new Name("Alice", "Burda", "Christophe"));
names.add(new Name("Ben", "Ashton", "Caine"));
names.add(new Name("Chane", "Bagwell", "Alex"));
names.add(new Name("Ann", "Clinton", "Brad"));
System.out.println("NAMES ORDERED BY FIRST NAME:");
Collections.sort(names, new NameComparator(NameMember.FIRSTNAME));
printNames(names);
System.out.println("\nNAMES ORDERED BY SECOND NAME:");
Collections.sort(names, new NameComparator(NameMember.SECONDNAME));
printNames(names);
System.out.println("\nNAMES ORDERED BY FATHERSNAME:");
Collections.sort(names, new NameComparator(NameMember.FATHERSNAME));
printNames(names);
}
private static void printNames(Collection<Name> names) {
names.stream().forEach(System.out::println);
}
I'm very new to Java and have been trying to set-up an ArrayList CustomerList that takes object Customer, where Customer has attributes from class IAddress. When calling the .add method in my main code however, I am given a NullPointerException error, which I assume is being given because my method isn't receiving anything to add to the ArrayList. I thought it was an issue with the attributes being initialised to empty strings, but when editing them to contain some information, the error still occured.
The ArrayList CustomerList
public class CustomerList {
public ArrayList<Customer> Clients;
public CustomerList() {
Clients = new ArrayList<>();
}
public void add(Customer src) {
Clients.add(src);
}
public void remove(Customer src) {
Clients.remove(src);
}
public void Display(JTextArea jClientsTextArea) {
for (int i = 0; i < Clients.size(); i++) {
Clients.get(i).Display(jClientsTextArea);
}
}
}
Receives Customer from this class
public class Customer {
private String FirstName;
private String Surname;
private IAddress HomeAddress;
public String DOB;
public Customer() {
FirstName = "";
Surname = "";
DOB = "01/01/1900";
HomeAddress = new IAddress();
public void Display(javax.swing.JTextArea jAddressTextArea) {
jAddressTextArea.setLineWrap(true);
jAddressTextArea.append("First Name: " + FirstName + "\n");
jAddressTextArea.append("Surname: " + Surname + "\n");
jAddressTextArea.append("DOB:" + DOB + "\n");
jAddressTextArea.append("Street: " + HomeAddress.getStreet() + "\n");
jAddressTextArea.append("House Name: " + HomeAddress.getHouseName() + "\n");
jAddressTextArea.append("House Number: " + HomeAddress.getHouseNo() + "\n");
jAddressTextArea.append("Area: " + HomeAddress.getArea() + "\n");
jAddressTextArea.append("Postcode: " + HomeAddress.getPostCode() + "\n");
jAddressTextArea.append("Town: " + HomeAddress.getTown() + "\n");
jAddressTextArea.append("Country: " + HomeAddress.getCountry() + "\n");
}
public void Edit(String strfirstname, String strsurname, String strDOB, String strStreet, String strHouseName, String strHouseNo, String strHouseArea, String strPostCode, String strTown, String strCountry) {
FirstName = strfirstname;
Surname = strsurname;
DOB = strDOB;
HomeAddress.setStreet(strStreet);
HomeAddress.setHouseName(strHouseName);
HomeAddress.setHouseNo(strHouseNo);
HomeAddress.setArea(strHouseArea);
HomeAddress.setPostCode(strPostCode);
HomeAddress.setTown(strTown);
HomeAddress.setCountry(strCountry);
}
}
Which receives attributes from IAddress
public class IAddress {
private String Name;
private String Street;
private String HouseNo;
private String HouseName;
private String Area;
private String PostCode;
private String Town;
private String Country;
public IAddress() {
Name = "";
Street = "";
HouseNo = "";
HouseName = "";
Area = "";
PostCode = "";
Town = "";
Country = "";
}
public void setName(String strName) {
Name = strName;
}
public void setStreet(String strStreet) {
Street = strStreet;
}
public void setHouseNo(String strHouseNo) {
HouseNo = strHouseNo;
}
public void setHouseName(String strHouseName) {
HouseName = strHouseName;
}
public void setArea(String strArea) {
Area = strArea;
}
public void setPostCode(String strPostCode) {
PostCode = strPostCode;
}
public void setTown(String strTown) {
Town = strTown;
}
public void setCountry(String strCountry) {
Country = strCountry;
}
}
I've been banging my head against this problem for hours and am ready for it to be something stupidly simple. Thank you.
In your code above the only reason why calling myCustomerList.add(...) could throw is that myCustomerList itself is null. This is because the Clients inside it is initialized in the constructor, and never set to null again. The value of src does not matter as well - the call to Clients.add(src) would succeed even if src is null.
You need to make sure that in your main you do initialize your customer list, like this:
CustomerList list = new CustomerList();