Java新手问题。 我想低估如何设置和存储对象被装箱的时间的原则。
代码:
封装
package com.Test;
public class Test_package {
private static int hour;
private static int minute;
private static int second;
public Test_package(){
this.hour = (int)(((System.currentTimeMillis()/1000) /60) / 60) % 24 + 3;
this.minute = (int)((System.currentTimeMillis() / 1000) /60 ) % 60;
this.second =(int)(System.currentTimeMillis() /1000) % 60;
}
public void getTime(){
System.out.println("Stundas:" + this.hour +" minute: " +this.minute + " sekunde:"+ this.second);
}
}
主要类别:
import com.Test.*;
public class Test {
public static void main(String[] args) {
Test_package objectTime = new Test_package();
objectTime.getTime();
}
}
我得到的是当前时间,这很好,但我想了解创建对象时创建对象时的原理,所以当我调用方法时.getTime()我得到时间创建对象时不是当前时间。
换句话说,我该如何存储时间。 或者我的代码是好的,但我不会看到我想要的结果,因为主要类重复执行它重新创建对象,因此我得到当前时间。
答案 0 :(得分:3)
你的代码是99%的代码。但是有一些问题。
1)说服自己显示创建时间,而不是现在在调用getTime()之前进行睡眠
Test_package objectTime = new Test_package();
Thread.sleep(300000); // sleep 5 mins
objectTime.getTime();
2)构造函数对getCurrentTime进行多次调用;大多数情况下,如果系统在错误的时刻拨打电话,这将是好的,那么你冒险剪切时间戳。鉴于呼叫的粒度,这只会在每分钟结束时出现问题,就像时钟即将翻身一样。要解决此问题,请调用System.currentTimeMillis一次并重用该值。
public Test_package(){
long nowMillis = System.currentTimeMillis();
this.hour = (int)(((nowMillis/1000) /60) / 60) % 24 + 3;
this.minute = (int)((nowMillis / 1000) /60 ) % 60;
this.second =(int)(nowMillis /1000) % 60;
}
3)您正在重复使用相同的变量,因此如果您创建了多个对象,则只会存储最后一个对象的时间戳。要修复此问题,请从小时,分钟和秒中删除每个字段中的关键字static。
4)你已经将时区硬编码为UTC的+3,可能不是你的问题,但值得引起人们的注意。执行此操作的常规方法是仅将millis存储为字段,然后使用time formater进行打印,可能是新的Date(millis).toString()就足够了,它将使用平台的默认时区。
5)你还应该知道currentTimeMillis可以以大于1的增量递增,从而报告在相同的时间戳创建了更多的对象。这取决于您运行的操作系统,而您几乎无法控制。在System上有一个单独的调用,它返回一个纳秒的相对计数并且具有更精细的粒度,但是该调用不会给出绝对时间,因此不适合你。我纯粹将其称为fyi。
答案 1 :(得分:1)
您的代码基本上没问题。
public class Test {
public static void main(String[] args) throws Exception {
Test_package objectTime = new Test_package();
Thread.sleep(300000); // sleep 5 mins
objectTime.getTime();
}
}
尝试以上操作。
您的主要“问题”仅在于您致电getTime()
在创建对象后立即创建。试着睡在两者之间
然后getTime
将打印5分钟前的时间,而不是
当前时间。
答案 2 :(得分:1)
由于您的时间变量为static
,因此每个变量只有一个实例,因此如果您创建了多个对象并从其中任何一个(或从类中)获取时间,那么您就可以了得到最后一个对象的创建时间。
也许这就是您的意图,但除此之外,只需从这些变量中删除static
关键字。
答案 3 :(得分:1)
您不想使用静态字段,或者最终会保存创建的 last 对象,而不是每个对象的创建时间。您还需要以毫秒为单位存储时间。
package com.Test;
public class Test_package {
private final Date created = new Date();
public void getTime() {
SimpleDateFormat sdf = new SimpleDateFormat(
"'Stundas:'HH' minute: 'mm' sekunde:'ss");
System.out.println(sdf.format(created));
}
}
答案 4 :(得分:0)
static
正如其他正确答案所述,您不应该将static
用于单个对象(实例)。
“静态”这个词有很长的扭曲历史,有C和Java,我们可以忽略它。结果是,在Java中,“静态”一词意味着“不是面向对象的”。 “静态”一词意味着我们希望在整个工作会话的内存中只保留一些数据(“状态”)。没有更好的地方可以保留它,我们将这些数据粘贴到内存中类的自己的表示上。使用普通的面向对象的非静态成员变量,每个对象(实例)都有自己的数据。对于Person
个对象,每个Person对象都有自己的firstName
和phoneNumber
值,而Person
类上的静态变量在内存周期中只有一个值。
具有非OOP语言背景的程序员可能会被static
个变量所吸引,因为它们看起来像全局变量。实际上,您可以使用静态变量和静态方法成功地创建Java程序,代码类似于非OOP语言。但是你会错过OOP带来的力量和简洁性。
请参阅问题What does the 'static' keyword do in a class?。
在处理日期时间数据时,通常最好使用日期时间数据类型。跟踪时间以毫秒为单位(自epoch以来的计数)很快变得笨拙,令人困惑,并且难以调试。此外,日期工作令人惊讶地复杂和棘手。只需在StackOverflow.com上搜索java date
即可查看日期时间工作的复杂程度。
例如,您的问题代码错误地将System.currentTimeMillis
视为时间,实际上它是日期和时间,从1970年的第一个时刻算起UTC时区。
您不会将数字作为位或文本处理为八位字节;我们已经将类定义为数据类型来处理和隐藏细节。所以你应该是日期时间课程,而不是自上帝以来的计数。
对于Java,我们有两个很好的日期时间库:
两者都有优势。幸运的是,你可以使用哪种更适合特定情况来混合和匹配两者。
Java还有一些用于日期工作的旧类,java.util.Date,java.util.Calendar,java.text.SimpleDateFormat和其他(都在java.time包之外)。不幸的是,这些类是众所周知的麻烦,历史和演变令人困惑,设计和实现都存在问题。避免他们。他们已被java.time
取代。如果需要,您可以转换为Joda-Time以及java.time。
在Java程序结束的main
方法结束时。内存中的所有数据都被清除,消失了。因此,如果您想要更长时间地存储数据,则必须保留它。也许写一个文件,或者把它放到数据库中。
在你的问题代码和下面的例子中,每次执行/运行程序时都会从头开始重新创建对象。因此,每个对象都会获得一个新的日期时间。
以下是Joda-Time 2.4中的一些示例代码。
我们有一个“Animal”类,可以跟踪它的对象何时被实例化(在运行时分配一块内存来存储其数据)。该时刻记录在Joda-Time库中定义的DateTime
类型的成员变量“objectCreation”中。
不是隐式依赖JVM的当前默认时区,而是分配时区。在这种情况下,我从proper time zone names列表中任意选择内罗毕。
作为使用static
的一个例子,我创建了三个常量,定义了预期的物种。这是一个实际的例子,我们避免和检测诸如“狗”的“dg”之类的拼写错误。
此示例捕获执行的开始和结束时间以显示一段时间。
package com.example.yourpackage;
import java.util.concurrent.TimeUnit;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Interval;
import org.joda.time.Period;
public class Animal
{
// Static vars exist once in memory, and can be accessed by *any* Animal object (or other objects).
static final String SPECIES_DOG = "dog";
static final String SPECIES_CAT = "cat";
static final String SPECIES_BIRD = "bird";
// Each instance (each Animal object) has its own value for each of these member variables.
DateTime objectCreation = null;
String species = null;
String name = null;
// Constructor method.
public Animal( String speciesArg , String nameArg )
{
if ( ( speciesArg.equals( Animal.SPECIES_DOG ) ) || ( speciesArg.equals( Animal.SPECIES_CAT ) ) || ( speciesArg.equals( Animal.SPECIES_BIRD ) ) ) {
// If we were passed an expected species, proceed.
this.objectCreation = DateTime.now( DateTimeZone.forID( "Africa/Nairobi" ) ); // Or DateTimeZone.UTC
this.species = speciesArg;
this.name = nameArg;
} else {
// Else we were passed an unexpected species.
// FIXME: Handle this error condition…
}
}
@Override
public String toString()
{
return "Animal{" + "objectCreation=" + objectCreation + ", species=" + species + ", name=" + name + '}';
}
public static void main( String[] args )
{
DateTime start = DateTime.now( DateTimeZone.forID( "Africa/Nairobi" ) );
Animal x = new Animal( "dog" , "Buddy" );
try {
TimeUnit.SECONDS.sleep( 3 );
} catch ( InterruptedException ex ) {
System.out.println( "Exception: " + ex ); // FIXME: Handle this error condition…
}
Animal y = new Animal( "dog" , "Rover" );
try {
TimeUnit.SECONDS.sleep( 5 );
} catch ( InterruptedException ex ) {
System.out.println( "Exception: " + ex ); // FIXME: Handle this error condition…
}
Animal z = new Animal( "bird" , "Polly" );
DateTime stop = DateTime.now( DateTimeZone.forID( "Africa/Nairobi" ) );
Interval interval = new Interval( start , stop );
Period period = interval.toPeriod();
System.out.println( "x: " + x );
System.out.println( "y: " + y );
System.out.println( "z: " + z );
System.out.println( "Interval: " + interval + " Period: " + period );
}
}
跑步时。
x: Animal{objectCreation=2014-09-16T10:17:00.636+03:00, species=dog, name=Buddy}
y: Animal{objectCreation=2014-09-16T10:17:03.635+03:00, species=dog, name=Rover}
z: Animal{objectCreation=2014-09-16T10:17:08.634+03:00, species=bird, name=Polly}
Interval: 2014-09-16T10:17:00.575+03:00/2014-09-16T10:17:08.634+03:00 Period: PT8.059S
提示:我建议避免使用“包”这个词作为命名类的一部分。单词package
是用于定义类的关键字,如问题代码的第一行所示。因此,将“包”混合到您的班级名称会令人困惑。