Why does getName() returns null? - java

EDIT: Thanks for all the answers! I didn't know that the object p in List.java is different from the p in Main.java. I passed it as a parameter and it works fine now. Thank you!
In Main.java:
System.out.println("Enter your name:");
String name = scan.next();
name+=scan.nextLine();
String words[]=name.split("\\s");
String capitalizeWord="";
for(String w:words){
String first=w.substring(0,1);
String afterfirst=w.substring(1);
capitalizeWord+=first.toUpperCase()+afterfirst+" ";
}
Person p = new Person(capitalizeWord);
In Person.java
private String name;
private int age;
Person(String newName){
name=newName;
}
Person(int newAge){
age=newAge;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
In List.java:
public void printInvoice(){
System.out.println("Enter your age:");
int age = scan.nextInt();
Person p = new Person(age);
System.out.println("Thank you for shopping with us, "+p.getName());
}
The last output is
Thank you for shopping with us, null
I don't know why this is happening. Did I do something wrong? I think the code is correct?

Each time you call a constructor you get a distinct instance of the object. The object created in Main.java with a name is stored in a local variable p that is only existing in the scope of Main.java. In List.java you create a second object with an age, but no name. It's also stored in a variable called p but that one is in the scope of List.java only and has nothing to do with the earlier created object.
It sounds like you want to add the name to the earlier object and not create a new one. For that you should pass the first object as a parameter to the code that adds the age, perhaps like this:
public void addAge(Person p) {
System.out.println("Enter your age:");
int age = scan.nextInt();
p.setAge(age); // will have to make this method in the Person class
System.out.println("Thank you for shopping with us, "+p.getName());
}
Calling Person p = new Person(age); gives a brand new Person object that has no name yet.

You have two constructors. One that accepts a string, one that accepts a number.
In your latest example you called the one that accepts a number and, since there's nothing initializing the name member, it gets initialized to null as default.
The p in Main.java has nothing to do with the p in List.java (they're two different variables), so initializing the former will have no effect on the latter.

As I can see in your List.java class, you have instantiated a new Person object with age as a parameter, so for that object, the name would be null, since the two reference variables are pointing to the different Person object
The first reference p to object Person has instantiated the person object using the contructor:-
Person(String name) {
this.name = name;
}
Second reference p to object Person has instantiated the person object using the constructor:-
Person(int age) {
this.age = age;
}
You should have used setter to set the property age to an already created Person object

code that create your person -> Person p = new Person(age);
constructor called -> Person(int newAge){
age=newAge;
}
This constructor let the name with his default value.. so null

Related

Set & Get Methods

Java I student here!
I am having a hard time understanding how to make set and get methods. I am working on a question in my textbook Java Programming, 9th Edition independently and I am asked to do the following:
"Create a class named Sandwich. Data fields include a String for the main ingredient (such as tuna), a String for bread type (such as wheat), ad a double for price (such as 4.99). Include methods to get and set values for each of these fields."
It then asks me to do this:
"Create an application named TestSandwich that instantiates one Sandwich object and demonstrates the use of the set and get methods."
So for the first part, I made a .java file with the following code:
public class Sandwich {
private String ingredient;
private String bread;
private double price;
public Sandwich(String ing, String bre, double pri) {
ingredient = ing;
bread = bre;
price = pri;
}
public void setIngredient(String ing) {
this.ingredient = ing;
}
public String getIngredient() {
return ingredient;
}
public String getBread() {
return bread;
}
public Double getPrice() {
return price;
}
}
For the second part, I did the following:
import java.util.Scanner;
public class TestSandwich {
public static void main(String[] args) {
String Ingredient;
String Bread;
Double Price;
Scanner keyboard = new Scanner(System.in);
System.out.println("MAKE A SANDWICH");
System.out.println("Enter an ingredient: ");
Ingredient = keyboard.nextLine();
System.out.println("Enter bread: ");
Bread = keyboard.nextLine();
System.out.println("Enter a price");
Price = keyboard.nextDouble();
Sandwich obj = new Sandwich(Ingredient, Bread, Price);
System.out.println("The ingredient is " + obj.getIngredient());
System.out.println("The bread is " + obj.getBread());
System.out.println("The price is " + obj.getPrice());
}
}
I completed this and it works well, however I realize that I did not create any set methods. Could someone explain to me a better way to do this according to the directions? I'm sure that this way works but I would like to do it by the book and be able to understand it better. I'm not sure where to start with creating the set methods. Please let me know. Thanks so much!
PS: This is NOT homework, I'm just trying to understand this a little better.
-Mark
Here you create an object with these values
Sandwich obj = new Sandwich(Ingredient, Bread, Price);
Here you create an empty object and then set the values
Sandwich obj = new Sandwich();
obj.setIngredient(Ingredient);
obj.setBread(Bread);
obj.setPrice(Price);
Consider this code in your class named Sandwich :
public Sandwich(String ing, String bre, double pri) {
ingredient = ing;
bread = bre;
price = pri;
}
This is called a constructor, a special kind of method that is having the same name as that of the class. But it does not return a value. This constructor is accepting three parameters, of which two are strings and one is a double value. In the constructor body you are actually setting values that are passed to the constructor as parameters and so you can consider this as a setter method which is setting three values at once.
Now consider this code inside the same class :
public void setIngredient(String ing) {
this.ingredient = ing;
}
This method is a setter method which sets only one value, i.e. ingredient. You can create other setter methods as well like this giving any name you want to. For example setBread and setPrice method inside the Sandwich class as follows:
public setBread(String bre) {
bread = bre;
}
public setPrice(double pri) {
price = pri;
}
You can either use the constructor to set the values or the "setter methods"(It is just a normal method that is used to accept and set the values). You can use a single method to set all the values in one go, which is what the constructor is doing or use individual methods to set each values like the setter methods we have defined.
If you are using a single method to set all values at once(in this case the constructor) then during the time of instantiating Sandwich class you need to pass all the values at once to the constructor like you did this :
Sandwich obj = new Sandwich(Ingredient, Bread, Price);
If you do not pass three variables to the constructor at once in the correct order, then compilation error will occur. As you already have a constructor setting three values, the other setter methods are not of great use except when you need to change the values afterwards. I hope this helps.
Simple go like:
System.out.println("Enter another price");
double newPrice = keyboard.nextDouble();
obj.setPrice(newPrice);
and print your obj before / after that call (and of course: #Overwrite toString() on that class to get meaningful output).

How to convert Object[] to java class

Is there a way to cast an Object array into a java class?,
Example: I have a class "Person" with the next attributes: Name, age, address. And i have an Object[] with this: [1]: "Peter", [2]: 20, [3]: "California 130".
I want to do something like this:
Person p = new Person();
Object[] o = new Object[2];
p = (Person) o;
I have to do this without set the values one by one, example:
p.setName((String)o[0]);
Is there a way?
Regards
You're trying to have the compiler convert an array of Object automagically into a a class with fields, and this just isn't possible. Instead you could create a constructor that takes an array of object and then assigns each item in the array into the fields of your class, but while this can be done, it has a bad code smell. Better to avoid use of Object arrays entirely, that is, arrays that hold items of different types. Instead deal with fields and parameters that have appropriate and actual types, and pass correctly typed items into your class's constructor. i.e.,
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
try something like this:
Person convert(Object[] o){
String name = (String) o[0];
int age = (int) o[1];
String address = (String) o[2];
Person p = new Person(name, age, address);
return p;
}
this method asks for this Object[] and returns a person with the information.
You cannot do it, as this would cause ClassCastException to be thrown. The reason is that because of inheritance and the is-a relationship.
Every Person object is an Object and every String object is of type Object. However, the opposite is not true. This is like saying every horse is a mammal, but not every mammal is a horse.
Create a method in the person class (setAttributes(Object[])for example) that sets the person attributes from the array values.

Method taking reference to an array of references?

I missed one of my lectures in Java, and the subject was classes, methods, constructors etc. The homework is one task:
Create a class Person, objects of which describe persons, and which
contains only two felds: name (String) and year of birth (int). In
this class, define
constructor taking name and year of birth;
constructor taking only name and setting the year of birth to default value 1990;
method isFemale returning true if this person is a woman (we assume, not very sensibly, that only women and all women have names ending
with the letter 'a'); otherwise the method returns false;
static function getOlder taking two references to objects of class Person and returning the reference to the older of these two persons;
static function getOldest taking the reference to an array of references to objects of class Person and returning the reference to
the oldest person represented in the array;
static function getYoungestFemale taking the reference to an array of refe- rences to objects of class Person and returning the reference
to the youngest woman represented in the array, or null if there is no
woman in the array.
In a separate class, write a main function in which the whole
functionality of the class Person is tested.
I checked some tutorials and explanations, I didn't go straight here asking for help but after 2 hours of ripping my hair out I've been only able to come up with this:
public class Person {
String name;
int yob; //year of birth
public Person() {
Person jan = new Person("Jan", 1995); //the names are polish
Person joanna = new Person("Joanna", 1993);
Person michal = new Person("Michal", 1980);
Person beata = new Person("Beata", 1979);
Person kazimierz = new Person("Kazimierz", 1998);
Person magdalena = new Person("Magdalena", 1999);
}
public Person(String name, int yob) {
this.name = name;
this.yob = yob;
}
public Person(String name) {
this.name = name;
this.yob = 1990;
}
public static boolean isFemale(String name) {
if(name.equals("Joanna")) {
return true;
} else {
return false;
}
}
public static String getOlder(Person x?, Person y?) { // if I understand the task correctly, I should reference any two names?
if(x?.yob>y?.yob) {
return x?.name;
} else {
return y?.name;
}
//getOldest and getYoungestFemale methods go here
}
}
However, I can't wrap my head around the last three steps. My brain is literally boiling. It would really help if anyone could explain the last three bullet points (getOlder reference to any 2 people and getOldest/getYoungestFemale)
If you don't have time to explain, some example of a "method taking a reference to an array" should be enough for me to get a basic understanding.
Thanks in advance.
Usually.. you don't call it "reference to an array of references of something" You just say "array of something". Even though arrays of objects are arrays of references to objects. Just like a variable for an object is just a reference to an object.
Type heyImAReference = new ImTheObject();
So when you write
Person person = new Person();
You'll have the class Person as type, person as a reference to an instance (or object) of that class and the resulting entity of new Person() as the actual thing that is being referenced. Usually called "instance" or in your case "object".
When it comes to arrays of persons and you do
Person[] persons = new Person[5];
You create via new Person[5] an array instance that has 5 slots, in each slot can go a Person instance figuratively, actually though you have 5 references. Person[0] being the first, Person[1] being the second and so on. So that is an "array of references to objects of class Person".
And persons is a reference to that. So it is a "reference to an array of references to objects of class Person"
static function getOldest taking the reference to an array of references to objects of class Person and returning the reference to the oldest person represented in the array
means nothing more than
static Person getOldest(Person[] persons) {
...
}
I would call that a method that takes an array of Persons and returns a Person. Though technically, it's all just references that go in and come out. The Person objects don't "move"
Firstly create another class which will have main method. Within main create an array:
Person[] parr = new Person[6];
//Then fill all your person to this array:
parr[0] = new Person("name", year);
parr[1] = ....
Then pass this array handler to your methods:
Person p1 = Person.findSomething(parr);
In Person class:
public static Person findSomething(Person[] parr){
for (Person p : parr){
if (p.name.endsWith("a")) return p;
}
return null;
}
Here are some hints which should help you work out the answer yourself without me giving away the solution ;)
1)
public static String getOlder(Person x?, Person y?) {
// if I understand the task correctly, I should reference any two names?
if(x?.yob>y?.yob) {
return x?.name;
} else {
return y?.name;
}
}
This code is almost correct! Just remove the question marks! Also remember that the older person will have an earlier yob. EDIT, also you need to return the reference to the person, not their name, so return either x or y.
2) getOldest and getYoungestWoman
Person[]
is an array of references to Person objects. You should be able to read up on how to loop through the elements of an array and compare values.
3) an extra: if you declare those 6 Person objects inside the constructor, you won't be able to access them in other methods of the class. it is ok to create the Person objects there, but you must declare them outside the constructor. Declare them in the class.

How can a string be used to call an object method in Java?

I have a class called "Skill" with a getName() method. I use it to return the name of the Skill objects that I create. When I try to compile my code, it says "Cannot find symbol- method getName()". Is there any way to get around this? For example, in my main method:
String[] playerSkill = new String[1];
playerSkill[0] = "a";
System.out.println(playerSkill[0].getName());
And in my Skill class:
public Skill(String n, String d, int p) {
name = n;
description = d;
power = p;
}
public String getName() {
return name;
}
I know I cannot make the String look like a Skill object:
System.out.println((Skill)playerSkill[0].getName());
The main problem is that the arrays are to be filled with user input so the arrays need to be String arrays. How would I get around this?
Your method getName is from class Skill and you try to invoke it from String class.
You should do something like this:
Skill[] playerSkill = new Skill[1];
playerSkill[0] = new Skill("name", "desc", 3);
System.out.println(playerSkill[0].getName());
When you are saying String[] playerSkill = new String[1]; That means that the array created is of String type and you ll only be able to call methods of String class. The element at playerSkill[0] can only hold object of String and not Skill
I think you want to achieve this
Skill[] playerSkill = new Skill[1];
playerSkill[0] = new Skill("a", "b", 0);
System.out.println(playerSkill[0].getName());
Since you mentioned you need to take input and then make the skill object. You can get the string, int from the console and then create the instances of Skill
Scanner sc = new Scanner(System.in);
String name = sc.next();
String desc = sc.next();
int x = sc.nextInt();
Skill s = new Skill(name, desc, x);
you need to modify these lines according to your stuff
Since the String object doesn't have a getName method attached to it, Java isn't going to allow you to call it on an instance of it.
Use the object that has the method attached to it. Instead of an array though (since you only create one space in it), just go with a regular instance.
Skill skill = new Skill("name", "desc", 10);
System.out.println(skill.getName());
This is important to note because you may run into situations in which other objects will have similarly named methods, but not give you the behavior you want. Always be specific about the type of object you're interacting with.
If you need such a behavior I suggest to create a POJO such as:
public class Player{
private String skill, name;
public setSkill(String skill){
this.skill = skill;
}
public getSkill(){ return this.skill;}
public setName(String name){
this.name=name;
}
public getName(){return this.name;}
}

'this' keyword in Java

I have a question regarding this in the following code. In the following, this.name will set the name. We could also do this using name = name, so my question is should the this pointer be used. This is not an homework
import java.io.*;
public class Employee{
String name;
int age;
String designation;
double salary;
//This is the constructor of the class Employee
public Employee(final String name){ //EDIT: Made parameter final
this.name = name;
//name= name; this is also correct
}
//Assign the age of the Employee to the variable age.
public void empAge(int empAge){
age = empAge;
}
//Assign the designation to the variable designation.
public void empDesignation(String empDesig){
designation = empDesig;
}
//Assign the salary to the variable salary.
public void empSalary(double empSalary){
salary = empSalary;
}
//Print the Employee details
public void printEmployee(){
System.out.println("Name:"+ name );
System.out.println("Age:" + age );
System.out.println("Designation:" + designation );
System.out.println("Salary:" + salary);
}
}
// name= name; this is also correct
This is not correct. It'll assign your parameter to itself. By using the this keyword, you're declaring which name you're using (i.e. the field on your Employee object).
You may wish to name the field differently from the parameter. However this means that all works well until someone automatically refactors your code to (perhaps inadvertently) declare the field and parameter as the same name!
For this reason you'll often see method signatures defined thus:
public Employee(final String name)
The final keyword prevents reassignment, and stops you from mistakenly reassigning the input parameter, and consequently not assigning to your field. Note also that if you declare the field as final, then compilation will fail if you don't make an assignment to that field. Using final is a good way to trap such errors and also enforce the immutability of an object (often a good thing - it contributes to a more reliable solution, especially in a threaded environment).
Well to avoid the confusion in cases like u mentioned name=name we uses this pointer to make it clear the we here mean class variable name .
So to make understand the reader here in this case we use this though there can be many other cases where (this) is more useful.
In some compilers name=name gives error as well
Notice that there are two things called name in your code. Your class Employee has member variable called name, and the constructor takes a parameter that's also called name.
What you want to do in the constructor is set the member variable name to the same value as the parameter name. To access the member variable, you have to use this.name, because name refers to the parameter - because the variables have the same name, the parameter is hiding the member variable.
Note that name = name; does not do the same thing as this.name = name;.
When you do name = name;, you assign the value of the parameter name to the parameter itself - not to the member variable. The compiler does not magically know that the first name is supposed to mean the member variable, and the second name is supposed to mean the parameter.
So, you need this in this case to refer explicitly to the member variable, instead of the parameter that is hiding the member variable.
In this case this is just a scope resolution/disambiguation.
public Employee(String name){
this.name = name;
// the above line will assign a value of parameter to instance variable
// name= name; this is also correct
// (**NO** the above line will assign a value of parameter to itself)
}
When the parameter name and your class variable names are same, then to differentiate between them, you write this.classVariable to identify the class variale
When you call a variable, the pointing one is the one who is the closest to your current scope.
So, if program is currently containing in memory a local variable toto and the wrapping class containing a field variable toto, you have to precise this keyword in order to access the field's one.
Otherwise, the field variable is said to be shadowed by the local variable and so doing toto = toto assigns the local parameter to itself (never useful) and not what you are expecting => the field variable.
Why make it so hard on yourself?
Just rewrite the signature/method like this:
public Employee(String _name) {
name = _name;
}
Always try to avoid variable hiding or other hard-to-read constructs. If you want your code to be maintainable, write it in such a way that everybody can understand it immediately. Even if you are the only one; you might forget what you meant in time.
This Keyword Program
public class ThisKeywordActivity extends Activity {
int a=20;
public ThisKeywordActivity(int a) { // this();
//this.a = a;
}
public ThisKeywordActivity()
{
System.out.println(" msg default Constructor ");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_this_keyword);
ThisKeywordActivity thisKeywordActivity2 = new ThisKeywordActivity(100);
thisKeywordActivity2.show(40);
}
public void show( int a)
{
System.out.println("msg a 2==="+a);
System.out.println("msg a 3==="+this.a);
}
}
Output
a2=40
a3=20

Categories