# 初识数据
# 变量
我们已经学习了最常用的输出语句System.out.println
, 想输出东西时可以这样:
System.out.println("something");
System.out.println("something");
System.out.println("something");
System.out.println("something");
System.out.println("something");
输出结果:
something
something
something
something
something
如果我想同时修改这些something
为some words
应该怎么做? 最简单的方法就是直接把它们改成some words
即可.
但是这样太麻烦了, 我们可以结合数学里方程的概念, 设一个变量, 输出的是这个变量, 这样只需要改变这个变量的值即可, 就像这样:
String str = "some words";
System.out.println(str);
System.out.println(str);
System.out.println(str);
System.out.println(str);
System.out.println(str);
这样输出的结果就是
some words
some words
some words
some words
some words
你可以认为变量是"临时存放值的场所", 我们可以临时把数据存在这里.
声明变量的方法是 变量的类型 + 空格 + 名称, 后面加一个等号并放入初始值.
# 基本数据类型
Java里总共有8个基本数据类型, 分别是字符类型char, 布尔类型boolean, 数值类型byte、short、int、long、float、double.
数值类型又可分为整数类型byte、short、int、long和浮点数类型float、double.
你可能会有疑问, 为什么数值类型有6种, 而不能只是1种叫number呢?
这是因为声明变量之后, JVM会先在内存里把这个变量要用到的内存空间给占住不让别人动. 就跟你吃馒头一样, 你永远都是先把馒头买到家, 然后再决定怎么吃.
也就是它们的区别在于占用的内存大小不一样, 比如byte只能存-128~127, 如果我写byte b = 129;
就会因为byte变量能存的不够那么大而报错(数值溢出错误).
char只能存一个字符, 比如char c = 'a';
, 注意Java里对字符串和字符的表示:
String str = "这是字符串"; //用的是英文双引号表示的
char c = 'A';//这是字符, 用的是英文单引号
String str2 = "B"; //字符串也可以是一个单字符
String str3 = ""; //也能是个空字符串
注意String
的S
是大写, 它不属于基本数据类型, 这是因为String
是一个类名, 全名叫做java.lang.String
.
基本数据类型不属于类, 你可以发现它们首字母是小写. 同理, int i = 0;
中i
不是对象.
如果你理解不了为什么, 你只需要记住这是一种特殊情况就可以了.
# 数组
如果我有许多int
类型的数据, 用什么才可以将它们一起存起来?
你可能想, 有多少创建多少变量不就好了.
如果我不知道有几个呢? 那么只能用数组来存储了.
注意, 数组本质也是一个对象, 但因为理解起来比较抽象, 这里不继续讨论数组是对象的问题了.
多维数组在此处不讨论, 其实本质就是某某类型数组类型的数组, 套娃而已.
int[] nums = new int[3]; //这个数组只能装10个数, 这里的上限最大是int类型的最大值
//数组元素的编号是从0开始的, 所以这三个数字分别是 0号, 1号, 2号
nums[0] = 1;
nums[1] = 666;
nums[2] = 9;
System.out.println(nums[1]); //输出第二个数字
结果是
666
你可以使用nums.length
查看数组的总长度(一开始设置的那个数).
你可以这样初始化一个数组:
int[] nums = {1,2,3,666,999,888,444};
这样这个数组的length
是7
, 举个例子, nums[3]
是666
(第四个数).
# 使用变量
public class Demo {
public static void main(String[] args){
int x=666;
System.out.println(x);
}
}
程序运行后, 会在控制台输出信息如下:
666
在程序的第三行, 我们定义了一个int类型的变量, 名字叫做x, 初始值为666. 既然是变量, 那么他可以在程序运行时, 在变量的有效范围内, 随时更改它的数值.
public class Demo2 {
public static void main(String[] args){
int x=666;
System.out.println(x);
x = 777;
System.out.println(x);
}
}
程序会在控制台中输出如下信息:
666
777
“=”符号是赋值符号, 如果想把语句x = 777;写为777 = x;是错误的, 因为“=”符号与数学上的“=”不一样, 赋值符号左面放被赋值的变量名, 右面放需要赋的值.
两个变量之间也可以相互赋值, 例如这样:
int x = 1, y = 2;
// 变量只有里面有数据的时候你才可以使用, 否则会报错
x = y;
System.out.println(x);
程序运行后, 在控制台中输出如下信息:
2
long
类型的变量可以存储的最大数字要比int类型更大.
Long.MAX_VAULE
代表Long类型可以存储的最大数字, Integer.MAX_VAULE
代表int类型可以存储的最大数字. 这也就是说, 在数学上, Long.MAX_VAULE
代表的数字要比Integer.MAX_VAULE
要大.
long
类型的变量与int类型的之间相互赋值, 如果试图把long
类型变量内的值赋到int
类型的变量当中, 会出现问题.
long a = 2;
int b = 3;
b = a;
System.out.println(b);
程序会出现问题, 导致程序无法编译.
# 运算
# 加减运算
public class Demo3{
public static void main(String[] args){
int x=666, y=777;
System.out.println(x+y);
}
}
上面的程序运行后在控制台输出信息如下:
1443
上述程序第三行使用了一种常用的定义变量方式, 这种方式看上去很骚, 并且能同时定义两个
int
类型的变量, 一个是初始值为666
的x
, 一个是初始值为777
的y
.但是如果要使用这种方式定义变量, 请警惕下面这种情况:
int x, y = 666;
上面的程序中, 我们定义了两个int类型的变量, 一个是x一个是y. 但是它们的初始值呢?x与y都是666吗?错, x没有初始值, 而y的初始值是666.
上面我们叙述了加法, 同理, 还有减法、乘法和除法.
可能你发现了, 键盘上并没有一个符号是 “×”, 也没有一个符号是“÷”. 想必你已经猜出来了, “*”是乘号, “/”是除号.
# 数字型的乘除运算
public class Demo4{
public static void main(String[] args){
int x=8, y=5;
System.out.println(x/y);
}
}
我们编写了这样的一个程序. 现在有两个数字, 一个是8, 一个是5, 相比程序运行结果应该是1.6, 而实际情况却与我们想象的结果不一样, 控制台中输出了这样的信息:
1
而我们都知道, 8除以5应当为1.6, 这是怎么回事呢?让我们试试看下面的这个程序:
public class Demo5{
public static void main(String[] args){
System.out.println(8.0/5.0);
}
}
程序运行后, 控制台输出信息如下:
1.6
那我们将“8.0”与“5.0”改为“8”与“5”呢?结果输出了“1”. 这证明, 小数与小数之间的加减乘除与整数与整数之间的加减乘除并不一样. 现在, 我们将不再称呼小数为“小数”, 而要称呼得更加严谨, 即“浮点数”. 整数与整数相除被称作整数除法, 浮点数与浮点数相除被称作浮点除法.
在小学的数学学习中, 我们知道, 被除数与除数相除, 会得到商和余数. 在上面的整数除法中, 8是被除数, 5是除数, 得到的数值1为其商, 这说明, 整数除法计算的结果是商, 而正如我们所见的一样, 浮点数除法得到的是一个确实的浮点数.
public class Demo6{
public static void main(String[] args){
System.out.println(7.0/3.0);
}
}
看上面的这个程序. 在上面的程序中, 我们进行了浮点数相除. 而我们得到的结果并不是无限个3, 而是有限个3. 这说明浮点数除法通常会丢失数据, 我们应当尽可能避免浮点数除法, 或使用更好地方案来计算浮点数相除.
public class Demo7{
public static void main(String[] args){
System.out.println(8.1/3);
}
}
在上面的程序中, 我们可以发现, 有一个数是8.1, 有一个数是3, 一个是整数, 一个是浮点数, 那这是什么神奇的操作呢?其实, 在计算中, 3会被转换为一个浮点数, 所以这个计算仍然是一个浮点数除法计算, 同理, 2.5+3得到的是5.5, 得到的数字是浮点数, 减法与乘法与此相同. 程序最终在控制台输出内容如下:
2.7
byte
、short
、int
和long
均为整数类型, 区别在于他们能存储的数字大小不一样, byte
<short
<int
<long
, 但不能将所有的整数都用long, 我们常用int, 滥用long
会无意义的浪费内存空间.
double是一种浮点数类型.
事实上, 8.1
就是一个double
类型的数据, 3
是一个int
类型的数据, 在计算过程中会被转换为double
类型的3.0
. 8.0
和5.0
都是double
类型的数据, 7.0
和3.0
都是double
类型的数据. 这也就是说:
int x=6; double y=2.0;
System.out.println(x/y);
在上面的代码里, 我们定义了int
类型的x
与double
类型的y
, 相除过程中将会把x
变量中的6
转换为double
类型的6.0
, 6.0
与2.0
相除得到3.0
, 所以程序在控制台中输出内容如下:
3.0
浮点数与整数相除, 浮点数永远不会被转换为整数, 永远是整数被转换为浮点数.
# 取余运算
刚才我们了解整数除法的时候, 知道了“/”可以取商, 但是怎么取余数呢?用“%”符号, 没错, 就是这个百分号. 就像这样
System.out.println( 8%5 );
在控制台中输出结果如下:
3
这是因为 8÷5=1 …… 3. 一个常用用法是, 利用取余来获得一个数字的个位数字, 例如, 26的个位数字是 26%10, 得到6.
# 隐性转换
long a = 2;
int b = 3;
b = a;
System.out.println(b);
正如我们刚才所见, 这个程序在刚才的运行中, 出现了问题.
那如果我们想要将int类型变量内的值赋值到long
类型的变量当中呢?
long a = 2;
int b = 3;
a = b;
System.out.println(a);
程序运行后, 会在控制台输出信息如下:
3
这说明这样做是可行的.
实质上, 在这个过程当中进行了隐性转换. 如上面的程序, 变量b
内的数据是int
类型的3
, 这个数据在赋值入变量a
当中时, 会被隐性转换为long
类型的3, 然后被赋值入long
类型的a
.
隐性转换的规则可以理解为“从低等级向高等级”. 我们可以假想为long
类型等级比int
类型高. 如果这样假想, 那么常见的四个整数类型可以按照这样的方式从低到高排序:
byte < short < int < long
# String类型
# String的使用
String
不是基本数据类型, 我们可以用这样的方式声明String
对象, 并用一个String
的变量把这个对象存起来:
String str = "hello!";
在后面你就会发现, Java里只有String对象的声明方式与其它对象声明方式不一样.
String有加法运算:
System.out.println("Hello" + " " +"world");
//这是三个String对象
//第一个是字符串 Hello
//第二个内容只有一个空格
//第三个是字符串 world
//用加号可以将它们连接起来
输出结果为:
Hello world
String类给出了许多方法, 比如replace
方法可以允许你将一个String对象里的所有某个字符串替换成另外一个字符串.
请打开Eclipse试一试. 先在main方法里这样输入:
String str = "test sleeping";
str = str
在这段代码第二行末尾的str后输入一个英文句号, 你会发现Eclipse为你列举出了String类里所有的方法, 这就是IDE的自动补齐代码功能.
我们不理会, 直接继续输入replace
, 补全后代码是这样:
String str = "test sleeping";
str = str.replace("sleeping","coding");
请尝试你是否可以使用System.out.println
语句将str
的内容输出出来.
你应该是这样做:
String str = "test sleeping";
str = str.replace("sleeping","coding");
System.out.println(str);
输出结果:
test coding
# 转义
我们表示字符串都是用双引号括起来的. 那问题来了, 如果字符串的内容里有一个双引号怎么办?
String wrongExample = "会是"这样"吗?" //这可以表示字符串的内容是 会是"这样"吗? 吗?
答案是不可以. 在Java中使用\
这样的斜杠代表转义.
在这里简单演示转义的基本用法, 其实还有更多转义的有趣用途, 请在网上自行搜索.
String rightExample = "会是\"这样\"吗?"
String rightExample = "\\";
//用System.out.println输出它们
输出结果
会是"这样"吗?
\
# 查阅JavaDoc
注意replace
方法经常会被写错成这样:
// 你应该写 str = str.replace("sleeping","coding");
str.replace("sleeping","coding");
为什么这样不对呢?
因为方法是可以有返回值的, replace
方法会把替换后的结果作为返回值返回给我们, 它的返回值是String
类型的. replace
不会改动原先对象的内容, 只是把新内容返回给我们而已.
所以, 我们要把新内容再赋值给str
才可以, 你可以这样试试看:
String str = "test sleeping"
System.out.println(str.replace("sleeping","coding"));
System.out.println(str);
输出结果为:
test coding
test sleeping
那你可能会有疑问, 我是怎么知道的这件事?
答案是, String是Java给出来的一个类, 官方是有说明文档的, 最具有说服力的官方文档就是JavaDoc, 所有官方给出的类都能在这里面找到具体的使用方法.
后续我们开发Bukkit插件时会不断地查阅BukkitAPI的JavaDoc, 不然我们根本不知道该怎么用.
在这里将不继续讲述JavaDoc怎么使用, 后续做Bukkit插件之前会讲述, 这里只是提一下.
# 常量
有些东西我们不希望别人修改, 这些量属于常量.
常量其实就是在变量前加上了final
关键字, 这样该常量在设定完毕初始值后将无法再次被更改.
final int finalTest = 1;
finalTest = 2; //修改它会报错
如果该变量前有public
和static
两个关键字修饰, 那么final
关键字应该在它们的后面.
← 类和方法的创建 关键字、类与方法深入 →