Why reference object has 04/10/2016? [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I didn't understand why date2 printing 04/10/2016,
1) i didn't call method which has RETURN
2) there are two methods, with same Parameter but diff output
MyDate date2 = new MyDate(4,10,2008);
System.out.println(date2);
----------------------------------------
//MyDate class
public class MyDate{
public int day;
public int month;
public int year;
public MyDate(){
}
//Constructor that takes 3 arguments
public MyDate(int m, int d, int y){
setDate(m, d, y);
}
//Methods
public String toString1(){
return day + "/" + month + "/" + year;
}
public String toString(){
return month + "/" + day + "/" + year;
}
public void setDate(int m, int d, int y){
day = d;
year = y;
month = m;
}
}

It internally invokes toString() when you try to convert an Object to String and in your case which is implemented to print it

I didn't understand why date2 printing 04/10/2016,
With the MyDate class and its toString() method, System.out.println(date2) should print 4/10/2016 since an int is not a String formater and so doesn't add a 0 prefix.
public class MyDate{
public int day;
public int month;
public int year;
...
public String toString(){
return month + "/" + day + "/" + year;
}
...
}
Edit for comment
As you are beginner, I will try to decompose but stay simple.
Your interrogation comes from what this method does :
System.out.println(date2);
First : you have to understand what this line means.
Here, you call the println() method of the out PrintStream field of the System class and you provide as parameter of the method the date2 variable which is an instance of MyDate.
Which should interest you here is what println() does.
The naming may make you guess that it has a relation with the display of something and it is the case but nothing is better than the javadoc and the source code of a class to understand it.
println() is a overloaded method of PrintStream. So you have to identify which one method is called. The single method which takes as parameter a type compatible with MyDate is void java.io.PrintStream.println(Object x).
For information, all classes derive from the Object class, therefore MyDate IS a Object.
Look at its javadoc :
java.io.PrintStream
void java.io.PrintStream.println(Object x)
Prints an Object and then terminate the line. This method calls at
first String.valueOf(x) to get the printed object's string value, then
behaves as though it invokes print(String) and then println().
Parameters: x The Object to be printed.
It is rather clear what the method does :
it calls String.valueOf(x) to get the String value of the x object
then it print the retrieved String value from x.
But what does String.valueOf(x) ?
There again, javadoc and code source will help you :
/**
* Returns the string representation of the {#code Object} argument.
*
* #param obj an {#code Object}.
* #return if the argument is {#code null}, then a string equal to
* {#code "null"}; otherwise, the value of
* {#code obj.toString()} is returned.
* #see java.lang.Object#toString()
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
it returns the result of the toString() method on the obj parameter if obj is not null, otherwhise it returns the "null" String.
Come back to your code now.
Inside, you declare these two methods :
public String toString1(){
return day + "/" + month + "/" + year;
}
public String toString(){
return month + "/" + day + "/" + year;
}
toString() is therefore logically called and you should remove or rename the toString1() method as it is error-prone named.
If you want to format your MyDate instance according to several formats, you should have two methods to perform it but you should avoid mixing a custom method with a toString() method.
You could have for example :
public String toStringInDDMMYYYY(){
...
}
public String toStringInMMDDYYYY(){
...
}
Besides, you could use SimpleDateFormat to format your date and use Date objects rather than custom Date objects but as you start in Java, I may understand what you test different things.

Related

How do I solve this NullPointerException Problem?

In here, I'm receiving a NullPointerException problem which seems to be related to my Date object in my class, but I can't figure it out.
My teacher said that everything works except that I'm returning the wrong data types for my date class, but I KNOW I'm returning a string, after all, that is what a getDate() method returns
I've tried putting in the code for the getDate() method itself, as in
"getMonth() + "/" + getDay() + "/" + getYear();
//main employee class
public class Employee
{
//2 attribute for employee
private String name;
private Date dateHired;
public boolean employeeType; //to check what type of employee, if
//false, then employee is salaried, otherwise hourly
//setter methods
public void setDateHired(int m, int d, int y)
{
Date dateHired = new Date(m,d,y);
}
public void setName(String s)
{
name = s;
}
public void setHoursWorked(int w)
{
}
//getter methods
protected String getDateHired()
{
return dateHired.getDate();
}
There isn't supposed to be an error, I reviewed this code hundreds of times and everything seems to be fine!
public void setDateHired(int m, int d, int y)
{
//dateHired is a local variable.. you're not modifying the class instance variable.
Date dateHired = new Date(m,d,y);
}
should be:
public void setDateHired(int m, int d, int y)
{
this.dateHired = new Date(m,d,y);
//or:
//dateHired = new Date(m,d,y);
}
Before turning to your actual questions, you have
private Date dateHired;
I recommend you don’t use the Date class. It was always poorly designed and is now long outdated. Despite its name it also doesn’t represent a date, but a moment in time at which there are two or three different dates around the globe. Instead use LocalDate from java.time, the modern Java date and time API. Use the tutorial link at the bottom.
For the NullPointerException Brandon has already explained how that came about from the following line:
Date dateHired = new Date(m,d,y);
Using LocalDate the line should be:
dateHired = LocalDate.of(y, m, d);
In new Date(m,d,y) you have got the arguments in the wrong order, you are treating year and month incorrectly and you are using a constructor that has been deprecated for decades, never ever do that.
My teacher said that everything works except that I'm returning the
wrong data types for my date class, but I KNOW I'm returning a string,
after all, that is what a getDate() method returns
The getDate method has been deprecated just as long, don’t use that one either. It also doesn’t give you the full date, and your teacher is correct, it doesn’t return a string, it returns an int.
I've tried putting in the code for the getDate() method itself, as in
getMonth() + "/" + getDay() + "/" + getYear();
You’d be surprised. However, rather than getting surprised and confused use a formatter for formatting your LocalDate into a string.
protected String getDateHired()
{
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
return dateHired.format(dateFormatter);
}
Example output from this method assuming US locale and a hire date of December 1, 2018:
12/1/18
ofLocalizedDate gives you a formatter for the default locale, so if your locale differs from US, you may be pleasantly surprised that the format of the string matches your expectations better than the quoted example. Normally one would declare the formatter a constant (a static final variable in the class), but I wasn’t sure that you had learned about this yet, so in this case I didn’t.
Long story short: Using the outdated Date class correctly is a lot harder than you would think because of its poor design. Don’t struggle with that one. Use of the modern LocalDate comes a lot more naturally. It numbers years and months the same way as humans do (at least since year 1 AD) and its method names are clearer, just mention a few of the many advantages.
Tutorial link: Oracle tutorial: Date Time explaining how to use java.time.

Should toString() ever return null? [duplicate]

This question already has answers here:
When we override the toString() method we should always return a string representation of the object?
(6 answers)
Closed 4 years ago.
Should the method toString() in java ever return null if no conversion could be done or should it return an empty string in that case instead?
null is not String so it is not allowed to return here. Check Java Docs:
Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.
it should return a meaningful string representation of the object. I wrote an example of how to use it and why it is useful:
public class Car {
private String make;
private int year;
public Car(String make, int year) {
this.make = make;
this.year = year;
}
#Overrride
public String toString() {
return "Car Make:" + make + "; Built Year: " + year;
}
}
Example:
Car myCar = new Car("Nissan", 1999);
Car yourCar = new Car("BMW", 2018);
System.out.println(myCar); // call toString() implicitly
System.out.println(yourCar);
It will print 2 lines and you can easily read the text and know which is your car!
Car Make:Nissan; Built Year: 1999
Car Make:BMW; Built Year: 2018
toString() returning null would be very bad API design. Clearly, if you are able to call toString() on it, the object is clearly not null. Otherwise, there would be a NullPointerException.
It really depends on the Object and what the use case is. Empty string is ok if you are using toString() to do real logic - e.g, if you use toString() as the key to a key-value store. If it is simply used for debugging/logging. Just print out all the fields. e.g, something like what MoreObjects.toStringHelper() does.
The Java API documentation, every recent version I have checked, says:
Returns:
a string representation of the object.
In other words null is not a defined return value. If you don't override the toString() method then you will always get a string that at least gives you the Object's ID.
Although this does not rule out that possibility of an overriding method returning null, any programmer who does this should expect a lot of NPEs from tools and frameworks that might be operating on that code.
My opinion: don't do it.
My question: what kind of object could not be represented by a string?

Making a getter that accesses another class in JAVA

Im learning OOP in Java and I am wondering how to create a getter that access data from a seperate class? I have a program that creates people with their names and birth dates. So I have 3 classes, PersonProgram(the main), People, and Date. The People class has the constructor for the Full names which include first name, last name, and birth date. The Date class has the constructor and setters for the date which includes 3 integers for the day, month, and year, and then a method that formats them into a string format. So in my main program, I have an option to print out information about whatever Person is created. So I call the getter of People with
Person[selection].getBirthDate;
and the getter in my People class is:
public Date getBirthDate() {
return birthDate;
}
but I want it to retrieve the formatted date from the toString method in my Date class. Can I just call the toString method from inside the getBirthDate getter?
Yes, it would be appropriate to use toString() here. In Date class:
#Override
public String toString(){
return year + "/" + month + "/" + day;
}
And in People class return a String instead of a Date object. This way you have a clean method interface, as you only want the Date to be read as whole String anyway:
public String getBirthDate() {
return birthDate.toString();
}
You can call from your main method :
person[index].getBirthDate().toString();
This will return the string you want since the toString method will be invoked on the Date class instance embeeded in the person instance.

What is the use of the 'new' operator for String in Java?

I have a really basic question about using new in java statement. For example, the return clause at the very end uses new for String. Why String here needs to be created? Under what kind of situations would people choose to use new?
public class A extends java.lang.Object {
public int number;
public String toString() {
return new String("Value : " + number);
}
}
Under no circumstance, since String is immutable there is no purpose in explicitly creating a copy of a string unless you really need a copy, from Javadoc, about the constructor:
Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.
An expression "Value : " + number already evaluates as a new String so return new String("Value : " + number) is equivalent to
String tmp = "Value : " + number;
return new String(tmp);
Which you can see creates an useless copy.
new String("Value:" + number) is redundant.
You attempt to instantiate a new String object by copying an existing string.Constructing new String object in this way is rarely necessary, and may cause performance problems if done often enough.
This is enough:
public class A extends java.lang.Object {
public int number;
public String toString() {
return "Value : " + number;
}
}

How are these methods being used without being called?

I have this pared down set of class files as an example of OO. They work perfectly but I do not understand how the println call from WorkerTest.java makes it all the way through Worker.java and to Date.java? Both Worker.java and Date.java have toString methods but neither are explicitly called, but I can tell from the output that both are used.
How is this working or what concept should I be studying?
public class WorkerTest {
public static void main( String[] args ) {
Date birth = new Date( 7, 15, 1922 );
Worker worker = new Worker( birth );
System.out.println( worker );
}
}
public class Worker {
private Date birthday;
public Worker( Date inboundBirthday ) {
birthday = inboundBirthday;
}
public String toString() {
return String.format( "Birthday: %s", birthday );
}
}
public class Date {
private int month;
private int day;
private int year;
public Date( int inboundMonth, int inboundDay, int inboundYear ) {
month = inboundMonth;
day = inboundDay;
year = inboundYear;
}
public String toString() {
return String.format( "%d/%d/%d", month, day, year );
}
}
Output:
Birthday: 7/15/1922
PrintStream.println(obj) calls obj.toString(). (Or more precisely: it calls String.valueOf(obj), which in turn calls obj.toString() unless obj is a null reference.)
See the Javadoc for java.io.PrintStream.
(Maybe what you're missing is that toString is actually a method on java.lang.Object? Worker and Date are merely overriding it. So all objects have that method, and JDK methods can rely on its existence. See the Javadoc for `java.lang.Object for a list of all the methods that all objects have.)
When println encounters a variable it tries to determine how it should be printed. It checks to see if the toString() method for the class in question has been overridden. So here's what's happening: println needs to print an instance of class worker, so it checks for the toString() method inside the Worker class. Inside the worker class it finds this line:
return String.format( "Birthday: %s", birthday );
Now it must figure out how to print birthday. Since birthday is an instance of Date, it checks for Date's toString() method. The key thing in understanding all this is that Java's built in classes have toString() methods too, you just don't see them. This is a good example because it shows you what's happening behind the scenes.
PrintStream.println() explicitly makes a call to String.valueOf(), which in turn calls Object.toString(), which is overridden in your two objects.

Categories