In an enum class, how can one cast values as dates? - java

In an enum class, how can one cast a value as the type java.util.date?
The enum still has to have a name.
I have tried:
ENUM_OPTION1(Date(10000000000L))
But I got an error saying that
"Symbol Date(long) wasn't recognized", even though I imported the class at the top of my file.

new Date( … )
Use new to instantiate a java.util.Date.
ENUM_OPTION1( new Date( 10_000_000_000L ) )
FYI, java.util.Date is a terrible class that was supplanted years ago by the java.time classes, specifically Instant.
Full example
Add a constructor on your enum. On each instance of the enum you declare, call the constructor. To that constructor, pass the specific date. See tutorial by Oracle.
public enum History {
US_DECLARATION_OF_INDEPENDENCE( LocalDate.of( 1776 , Month.July , 4 ) ) ,
US_CONSTITIUTION_APPROVED( LocalDate.of( 1787 , 9 , 17 ) )
;
private LocalDate localDate ;
// Constructor
public History( LocalDate ld ) {
Objects.requireNonNull( ld ) ;
this.localDate = ld ;
}
// Getter
public LocalDate getLocalDate() {
return this.localDate ;
}
}
To use this enum, call the instance method on one of the named constant instances.
LocalDate ld = History.US_DECLARATION_OF_INDEPENDENCE.getLocalDate() ;

Related

How to create immutable object from mutable in java? [duplicate]

This question already has answers here:
How to create immutable objects in Java?
(14 answers)
Closed 2 years ago.
How to create immutable Planet so the name doesn't change? I am struggling as I think it is immutable project with mutable object. Correct me if I am wrong.
Every time I change name in the output also changes. Am I missing something?
I tried to do all fields private and final (not in this example) but I think I am missing some code to work.
I know java.util.Date is deprecated but this is just for example.
import java.util.Date;
public final class Planet {
String name;
private final Date discoveryDate;
public Planet (String name, Date discoveryDate) {
this.name = name;
this.discoveryDate = new Date(discoveryDate.getTime());
}
public String getName()
return name;
}
public Date getDiscoveryDate() {
return new Date(discoveryDate.getTime());
}
public static void main(String [] args) {
Planet Earth = new Planet("Earth Planet", new Date(2020,01,16,17,28));
System.out.println("Earth");
System.out.println("------------------------------------");
System.out.println("Earth.getName: " + Earth.getName());
System.out.println("Earth.getDiscoveryDate: " + Earth.getDiscoveryDate());
}
}
tl;dr
Either:
Make a record like this, in Java 16 and later:public record Planet( String name , LocalDate discovered ) {}
Or, before Java 16, make a class where you:
Mark all member fields final and private.
Make getter methods as needed, but no setter methods.
Record
Just use the new records feature in Java 16 (previewed in Java 15).
Define your class as a record when its main job is to transparently and immutably carry data. The compiler implicitly creates a constructor, the getters, hashCode & equals, and toString.
Notice that the getter methods implicitly defined in a record do not begin with the JavaBeans-style get… wording. The getter method is simply the name of member field as defined in the parentheses following the class name.
Of course, if your getter methods provide access to an object that is itself mutable, being contained in a record does nothing to stop the calling programmer from mutating the contained object. Notice in the example class next that both String and LocalDate classes are themselves immutable by design. So the mutability of a contained object is a non-issue here.
package org.example;
import java.time.LocalDate;
public record Planet( String name , LocalDate discovered )
{
}
Using that record.
Planet Earth = new Planet( "Earth" , LocalDate.of( 2020 , 1 , 16 ) );
System.out.println( "Earth" );
System.out.println( "------------------------------------" );
System.out.println( "Earth.name: " + Earth.name() );
System.out.println( "Earth.discovered: " + Earth.discovered() );
When run.
Earth
------------------------------------
Earth.name: Earth
Earth.discovered: 2020-01-16
Class
Without the records feature, to make sure a class is immutable you should:
Mark the member fields final. This means the field cannot be assigned a different object after the constructor has finished.
Mark the member fields private. This means objects of other classes will not have direct access to read or change those fields.
Provide getter methods, if needed, but no setter methods. By convention, the JavaBeans-style get… or is… naming is used.
You should also provide appropriate override implementations of hashCode, equals, and toString. Your IDE will help generate the source code for those.
package org.example;
import java.time.LocalDate;
import java.util.Objects;
public class Planète
{
// Member fields
final String name;
final LocalDate discovered;
// Constructors
public Planète ( String name , LocalDate discovered )
{
Objects.requireNonNull( name );
Objects.requireNonNull( discovered );
this.name = name;
this.discovered = discovered;
}
// Getters (read-only immutable class, no setters)
public String getName ( ) { return this.name; }
public LocalDate getDiscovered ( ) { return this.discovered; }
// Object class overrides
#Override
public boolean equals ( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
Planète planète = ( Planète ) o;
return getName().equals( planète.getName() ) && getDiscovered().equals( planète.getDiscovered() );
}
#Override
public int hashCode ( )
{
return Objects.hash( getName() , getDiscovered() );
}
#Override
public String toString ( )
{
return "Planète{ " +
"name='" + name + '\'' +
" | discovered=" + discovered +
" }";
}
}
Using that class.
Planète Earth = new Planète( "Earth" , LocalDate.of( 2020 , 1 , 16 ) );
System.out.println( "Earth" );
System.out.println( "------------------------------------" );
System.out.println( "Earth.getName: " + Earth.getName() );
System.out.println( "Earth.getDiscoveryDate: " + Earth.getDiscovered() );
Side issues
Do not start a decimal integer literal with 0. The leading zero makes the number octal rather decimal. So your code passing 2020,01,16 should be 2020,1,16.
Never use the Date class, nor Calendar or SimpleDateFormat. These terrible classes are now legacy, supplanted years ago by the modern java.time classes defined in JSR 310. In code above, we used java.time.LocalDate to represent a date-only value, without a time-of-day and without a time zone.
Planet is immutable but field name should be private.

call staic method with instance class (LocalDate

my question is about the class LocalDate have a static method of that return a new instance of the classe example
LocalDate local = LocalDate.of(2019,9,21);
the probleme is that i can't call the method of with instance class localDate
(local.of(..) !!!!!!!!!???)
thanks for help :)
The static method LocalDate of(int year, int month, int dayOfMonth) Obtains an instance of LocalDate from a year, month and day. so you must use a reference of a LocalDate object to store the returned instance.
LocalDate local = LocalDate.of(2019,9,21);

Java Custom Data Type

I wanted to create a class with a custom data type that returns the class object. Consider a class Custom:
public class Custom {
// Some fields.
public Custom(String custom) {
// Some Text.
}
// Some Methods.
public void customMethod() {
// Some Code.
}
}
Now, consider a second class TestCustom:
public class TestCustom {
public static void main(String[] args) {
Custom custom = new Custom("Custom");
System.out.println(custom); // This should print "Custom"
custom.customMethod(); // This should perform the action
}
}
So, the question how to get the value custom on instantiating an object instead of memory location. Like what I get is:
Custom#279f2327
The java.util.Date class returns the current date. This can be seen as the constructor for the class is
public Date() {
this(System.currentTimeMillis());
}
For example, the following code would print out the current date:
DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date date = new Date();
System.out.println(format.format(date));
The Answer by ML72 is correct and should be accepted. The java.util.Date constructor captures the current moment in UTC.
java.time
The java.util.Date class is terrible, for many reasons. That class is now legacy, supplanted years ago but the java.time classes as of the adoption of JSR 310.
The java.time classes avoid constructors, instead using factory methods.
The replacement for java.util.Date is java.time.Instant. To capture the current moment in UTC, call the class method .now().
Instant instant = Instant.now() ;
If you want the current moment as seen through the wall-clock time used by the people of a particular region (a time zone), use ZoneId to get a ZonedDateTime object. Notice again the factory method rather than a constructor.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
Adjust to UTC by extracting an Instant.
Instant instant = zdt.toInstant() ;
Override the toString() method, as it is automatically invoked when you try to display an object:
Add a field. For example;
private String value;
In the constructor, add the following code:
value = custom;
this will assign a value passed to the constructor as a parameter, to the value field.
And finally override the toString() method as follows:
#Override
public String toString() {
return value;
}
Now, when you display the value of the custom object, the overridden toString() method will be invoked and the argument will be displayed instead of the memory address. Whereas methods of the object will work as they are programmed to work. There is nothing to be changed with them.

Why can LocalDateTime return the instance?

LocalDateTime is abstract class. So I cannot write:
LocalDateTime value = new LocalDateTime(); //error
If I want to get its instance, I have to write:
LocalDateTime value = LocalDateTime.now(); //not error
I have a question, Why can LocalDateTime return the instance? It's an abstract class.
I saw the overview, but I could not find it...
LocalDateTime is not an abstract class.
public final class LocalDateTime
implements Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>, Serializable {
It has private constructors, so direct instantiation is not possible. Factory method such now(), now(ZoneId) etc are used to create instances.
LocalDateTime is an immutable date-time object that represents a date-time.
This class does not store or represent a time-zone. Instead, it is a description of the date. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.
Hence it has static methods e.g.
LocalDateTime desc = LocalDateTime.now();

Static Variables Not Affecting Other Objects in Java Calendar Class

Since the Calendar class in Java has static data fields such as DATE, why don't the other objects change when the static field is modified?
I have made two different Gregorian Calendars and thought static data fields changed the value for all of the objects instead of one.
import java.util.Calendar;
import java.util.GregorianCalendar;
public class TEST {
public static void main(String[] args) {
GregorianCalendar cal = new GregorianCalendar();
System.out.println(cal.get(Calendar.DATE));
GregorianCalendar cal2 = new GregorianCalendar();
cal2.set(Calendar.DATE, 12);
System.out.println(cal2.get(Calendar.DATE));
System.out.println(cal.get(Calendar.DATE));
}
}
Calendar.DATE is not a static field, it's a static variable that's used to reference which type of value you want to set/get in a specific Calendar instance.
If you look at the actual source code of java.util.Calendar you would see that it has an internal int array that holds all the values, i.e. day, month, year, etc.
Calendar.DATE is just a nice way of referencing the fifth element of that array.
Declaration of member in the Java 8 source code.
/**
* Field number for <code>get</code> and <code>set</code> indicating the
* day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
* The first day of the month has value 1.
*
* #see #DAY_OF_MONTH
*/
public final static int DATE = 5;
The Answer by rorschach is correct and should be accepted.
Also, you are using old date-time classes that have proven to be poorly designed, confusing, and troublesome. Avoid them. They have been supplanted by the java.time classes.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate nextWeek = today.plusWeeks( 1 );
LocalDate midMonth = today.withDayOfMonth( 15 );
LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );
LocalDate secondTuesdayOfThisMonth = today.with( TemporalAdjusters.dayOfWeekInMonth( 2 , DayOfWeek.TUESDAY ) );

Categories