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.
Related
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 wrote a test program in java in which the object has 3 parameters:
id, name and age.
The name and age are initialised using constructor but id should be incremented automatically from the last id. (and it should start from 1 for 1st created object).
I used id as static variable to achieve the same.
import java.util.*;
class Test
{
private static int id = 1;
private int age;
private String name;
public Test(String name, int age)
{
this.id = id;
this.age = age;
this.name = name;
id++;
}
public String toString()
{
return id + " " + name + "," + age;
}
public static void main(String args[])
{
Test c1 = new Test("A", 12);
Test c2 = new Test("B", 32);
Test c3 = new Test("C", 58);
Test c4 = new Test("D", 17);
Test c5 = new Test("E", 42);
ArrayList<Test> testList = new ArrayList<Test>();
testList.add(c1);
testList.add(c2);
testList.add(c3);
testList.add(c4);
testList.add(c5);
for(int i = 0; i < testList.size(); i++)
System.out.println(testList.get(i).toString());
}
}
But in the output I am getting same id for all the test objects.
Can anyone please explain why this is happening ?
Any help will be highly appreciated.
A static variable means that the variable is shared between all the instances of the given class, if you change the value of a static variable in one of the instances it will be changed in all.
What you want to accomplish probably is doable in the next way:
class Test
{
public static int counter = 1;
private int id;
private int age;
private String name;
public Test(String name, int age)
{
this.id = counter;
this.age = age;
this.name = name;
counter++;
}
public String toString()
{
return id + " " + name + "," + age;
}
....
Make the counter public, you might actually need to reference it from outside the class instance, or if you cannot afford to expose it as public make it private and create a static getter for it which will allow you to get the current id counter from outside the class.
Another option is to use the Factory Pattern but probably that is not needed for this particular case.
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);
I have super class called pojo. I have a subclass called ExtendPojo.
pojo.java
package com.java.pojo;
public class pojo {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public long getNumber() {
return number;
}
public void setNumber(long number) {
this.number = number;
}
public String toString() {
return "pojo [name=" + name + ", age=" + age + ", number=" + number + "]";
}
private String name;
private int age;
private long number;
}
ExtendPojo.java
package com.java.pojo;
public class ExtendPojo extends pojo{
public static void main(String[] args) {
pojo obj = new pojo();
obj.setName("santhosh");
ExtendPojo exObj = new ExtendPojo();
exObj.setName("mahesh");//It is not overriding
System.out.println(obj.getName());//it prints santhosh.
}
public void setName(String name){
super.setName(name);
}
}
You are creating two independent objects.
First you create an object and name it santhosh. This object is referenced by the obj variable.
pojo obj = new pojo();
obj.setName("santhosh");
Then you create a second object, which is referenced by the exObj variable.
ExtendPojo exObj = new ExtendPojo();
It doesn't have a name yet, since it's a new object and you haven't assigned the name. You then give it a name.
exObj.setName("mahesh");//It is not overriding
Now you print the name of the first object, which hasn't changed.
System.out.println(obj.getName());//it prints santhosh.
The code is doing exactly what you asked it to do.
If you intended the two variables to reference the same object, you'd do this:
ExtendPojo exObj = new ExtendPojo();
pojo obj = exObj ;//Same object, new variable, different type
obj.setName("santhosh");
exObj.setName("mahesh");//It is working now
System.out.println(obj.getName());//it prints mahesh.
I have gone through the Inheritance and method overriding concepts and clarified my doubts :)
public class ExtendPojo extends Pojo{
public static void main(String[] args) {
Pojo obj = new Pojo();
obj.setName("santhosh");
Pojo obj1 = new ExtendPojo();
obj1.setName("mahesh");//It is overriding now
System.out.println(obj1.getName());//it prints mahesh.
}
}
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