java 数据库中存储对象
上次更新时间:2020年1月
尽管贪睡按钮可能是闹钟上最常用的按钮,但即使是简单的AlarmClock
类也需要更多功能。 例如,您可能想控制闹钟在小睡模式下停留多长时间。 为了添加这样的功能,您需要了解Java如何控制数据。
开发人员使用Java中的变量来保存数据,所有变量都具有数据类型和名称。 数据类型确定变量可以保存的值。 在本教程中,您将学习整数类型如何保存整数,浮点类型如何保存实数以及字符串类型如何保存字符串。 然后,您将开始在Java类中使用实例变量。
变量和原始类型
称为基本类型 ,整数和浮点类型是Java中最简单的数据类型。 以下程序说明了整数类型,它可以同时包含正整数和负整数。 该程序还说明了注释,这些注释记录了您的代码,但丝毫不影响该程序。
/*
* This is also a comment. The compiler ignores everything from
* the first /* until a "star slash" which ends the comment.
*
* Here's the "star slash" that ends the comment.
*/
public class IntegerTest {
public static void main(String[] args) {
// Here's the declaration of an int variable called anInteger,
// which you give an initial value of 100.
int anInteger = 100; // Declare and initialize anInteger
System.out.println(anInteger); // Outputs 100
// You can also do arithmetic with primitive types, using the
// standard arithmetic operators.
anInteger = 100 + 100;
System.out.println(anInteger); // Outputs 200
}
}
Java还使用浮点类型,该类型可以包含实数,即包含小数位的数字。 这是一个示例程序:
public class DoubleTest {
public static void main(String[] args) {
// Here's the declaration of a double variable called aDouble.
// You also give aDouble an initial value of 5.76.
double aDouble = 5.76; // Declare and initialize aDouble
System.out.println(aDouble); // Outputs 5.76
// You can also do arithmetic with floating point types.
aDouble = 5.76 + 1.45;
System.out.println(aDouble); // Outputs 7.21
}
}
尝试运行上面的程序。 请记住,必须先编译才能运行它们:
javac *.java
java IntegerTest
java DoubleTest
Java使用四种整数类型和两种浮点类型,它们都拥有不同的数字范围并占用不同的存储空间,如下表所示。
整体类型
类型 | 字节 | 短 | 整数 | 长 |
---|---|---|---|---|
大小(位) | 8 | 16 | 32 | 64 |
范围 | -128至127 | -32,768至32,767 | -2,147,483,648至2,147,483,647 | -2 63至2 63 -1 |
浮点类型(IEEE 754格式)
类型 | 单精度浮点 | 双精度浮点 |
---|---|---|
大小(位) | 32 | 64 |
范围 | +/- 1.18x10 -38至+/- 3.4x10 38 | +/- 2.23x10 -308至+/- 1.8x10 308 |
字符串类型保存字符串,并以与整数和浮点类型处理数字不同的方式处理字符串。 Java语言包括一个String
类来表示字符串。 您可以使用String
类型声明一个字符串,并使用带引号的字符串(包含在双引号中的一系列字符)对其进行初始化,如下所示。 您还可以使用+
运算符组合两个字符串。
// Code fragment
// Declaration of variable s of type String,
// and initialization with quoted string "Hello."
String s = "Hello";
// Concatenation of string in s with quoted string " World"
String t = s + " World";
System.out.println(t); // OutputsHello World
可变范围
除类型外, 范围也是变量的重要特征。 范围确定何时创建和销毁变量以及开发人员可以在程序中访问该变量的位置。 在程序中声明变量的位置决定了变量的范围。
到目前为止,我已经讨论了局部变量 ,该局部变量包含您在方法中使用的临时数据。 您可以在方法内部声明局部变量,并且只能从这些方法内部访问它们。 这意味着你只能检索局部变量anInteger
,您在使用IntegerTest
和aDouble
,您在使用DoubleTest
,从他们被宣布和其他地方的主要方法。
您可以在任何方法中声明局部变量。 下面的示例代码在AlarmClock snooze()
方法中声明了一个局部变量:
public class AlarmClock {
public void snooze() {
// Snooze time in millisecond = 5 secs
long snoozeInterval = 5000;
System.out.println("ZZZZZ for: " + snoozeInterval);
}
}
您只能从snoozeInterval
snooze()
方法进入snoozeInterval
,这是您声明snoozeInterval, as shown here:
public class AlarmClockTest {
public static void main(String[] args) {
AlarmClock aClock = new AlarmClock();
aClock.snooze(); // This is still fine.
// The next line of code is anERROR .
// You can't access snoozeInterval outside the snooze method.
snoozeInterval = 10000;
}
}
方法参数
方法参数的范围类似于局部变量,是另一种变量。 方法参数将参数传递给方法。 声明该方法时,可以在参数列表中指定其参数。 您在调用方法时传递参数。 方法参数的作用与局部变量类似,因为它们位于它们所链接的方法的范围内,并且可以在整个方法中使用。 但是,与局部变量不同,方法参数在调用方法时从调用方获取值。 这是闹钟的修改形式,使您可以传递snoozeInterval
。
public class AlarmClock {
public void snooze(long snoozeInterval) {
System.out.println("ZZZZZ for: " + snoozeInterval);
}
}
public class AlarmClockTest {
public static void main(String[] args) {
AlarmClock aClock = new AlarmClock();
// Pass in the snooze interval when you call the method.
aClock.snooze(10000); // Snooze for 10000 msecs.
}
}
成员变量:对象如何存储数据
局部变量很有用,但是由于它们仅提供临时存储,因此其值受到限制。 由于它们的生命周期跨越声明它们的方法的长度,因此局部变量与记事本进行比较,该记事本在您每次接到电话时出现,但在挂断电话时消失。 该设置对于记笔记非常有用,但是有时您需要一些更永久的东西。 程序员要做什么? 输入成员变量 。
成员变量(其中有实例和静态两个)构成类的一部分。
范围和寿命可变
开发人员实现实例变量以包含对类有用的数据。 一个实例变量在其范围和生存期方面与本地变量不同。 整个类构成一个实例变量的范围,而不是声明它的方法的范围。 换句话说,开发人员可以在类中的任何位置访问实例变量。 另外,实例变量的生存期不依赖于该类的任何特定方法。 也就是说,它的生存期就是包含它的实例的生存期。
实例是从类定义中设计的蓝图创建的实际对象。 您在类定义中声明实例变量,从而影响从蓝图创建的每个实例。 每个实例都包含那些实例变量,并且变量中保存的数据因实例而异。
考虑AlarmClock
类。 将snoozeInterval
传递到snoozeInterval
snooze()
方法中并不是一个很好的设计。 想象一下,每次您摸索到贪睡按钮时都必须在闹钟上输入贪睡间隔。 而是给整个闹钟一个snoozeInterval
。 使用AlarmClock
类中的实例变量完成此操作,如下所示:
public class AlarmClock {
// You declare snoozeInterval here. This makes it an instance variable.
// You also initialize it here.
long m_snoozeInterval = 5000; // Snooze time in millisecond = 5 secs.
public void snooze() {
// You can still get to m_snoozeInterval in an AlarmClock method
// because you are within the scope of the class.
System.out.println("ZZZZZ for: " + m_snoozeInterval);
}
}
您可以在声明实例变量的类中的几乎任何位置访问实例变量。 为了对此进行技术性介绍,您可以在类范围内声明实例变量,然后可以从该范围内的几乎任何位置检索它。 实际上,您可以在开始类的第一个大括号和右括号之间的任何位置访问变量。 由于您还在类范围内声明方法,因此它们也可以访问实例变量。
只要实例存在,您还可以从类外部访问实例变量,并且您具有引用该实例的变量。 要通过实例检索实例变量,可以将点运算符与实例一起使用。 这可能不是访问变量的理想方法,但出于说明目的,现在以这种方式完成该操作:
public class AlarmClockTest {
public static void main(String[] args) {
// Create two clocks. Each has its own m_snoozeInterval
AlarmClock aClock1 = new AlarmClock();
AlarmClock aClock2 = new AlarmClock();
// Change aClock2
// You'll soon see that there are much better ways to do this.
aClock2.m_snoozeInterval = 10000;
aClock1.snooze(); // Snooze with aClock1's interval
aClock2.snooze(); // Snooze with aClock2's interval
}
}
尝试一下该程序,您会看到aClock1
的间隔为5,000,而aClock2
的间隔为10,000。 同样,每个实例都有其自己的实例数据。
别忘了,类定义只是一个蓝图,因此在您从该蓝图创建实例之前,实例变量实际上并不存在。 一个类的每个实例都有自己的实例变量副本,并且该蓝图定义了这些实例变量将是什么。
![闹钟变量的两个实例](https://images.idgesg.net/images/article/2020/01/snooze-100827569-large.jpg)
图1.一个带有实例变量的AlarmClock的两个实例
封装形式
封装是面向对象编程的基础之一。 使用封装时,用户通过公开的行为与类型进行交互,而不是直接与内部实现进行交互。 通过封装,您可以隐藏类型实现的详细信息。 在Java中,封装基本上转化为以下简单准则:“不要直接访问对象的数据;请使用其方法。”
这是一个基本的想法,但它减轻了我们作为程序员的生活。 例如,假设您想指示一个Person
对象站起来。 如果没有封装,您的命令可能会如下所示:“好吧,我想您需要在腿的前面收紧这块肌肉,在腿的后面收紧这块肌肉。嗯-需要弯曲腰部也是如此。哪些肌肉引发了这种运动?需要收紧这些肌肉,松开那些。哎呀!忘了另一条腿。该死的,看它-不要翻倒……” 使用封装,您只需要调用standUp()
方法。 很简单,是吗?
封装的一些优点:
- 详细信息的抽象 :用户在更高级别上与类型进行交互。 如果使用
standUp()
方法,则不再需要知道启动该动作所需的所有肌肉。 - 与变更隔离:内部实施的变更不会影响用户。 如果一个人扭伤了脚踝,并依靠拐杖一会儿,则用户仍然仅调用
standUp()
方法。 - 正确性:用户不能随意更改对象的内部。 他们只能完成您所允许的编写方法。
这是一个简短的示例,其中封装明显有助于提高程序的准确性:
// Bad -- doesn't use encapsulation
public class Person {
int m_age;
}
public class PersonTest {
public static void main(String[] args) {
Person p = new Person();
p.m_age = -5; // Hey -- how can someone be minus 5 years old?
}
}
// Better - uses encapsulation
public class Person {
int m_age;
public void setAge(int age) {
// Check to make sure age is greater than 0. I'll talk more about
// if statements at another time.
if (age > 0) {
m_age = age;
}
}
}
public class PersonTest {
public static void main(String[] args) {
Person p = new Person();
p.setAge(-5); // Won't have any effect now.
}
}
即使是那个简单的程序,也显示了如果直接访问类的内部数据将如何陷入麻烦。 程序越大,越复杂,封装就越重要。 还请记住,许多程序从小开始,然后无限期发展,因此从一开始就正确设计它们至关重要。 要将封装应用于AlarmClock
,您可以仅创建方法来控制暂停间隔。
关于方法的注释
方法可以返回调用者使用的值。 要返回值,请声明非空返回类型,并使用return
语句。 下面示例中显示的getSnoozeInterval()
方法对此进行了说明。
编写程序
翻译自: https://www.infoworld.com/article/2076301/learn-how-to-store-data-in-objects.html
java 数据库中存储对象