基础篇-1.2Java世界的规章制度(上)
1 Java标识符
在Java语言中,有类、对象、方法、变量、接口和自定义数据类型等等,他们的名字并不是确定的,需要我们自己命名。而Java标识符就是用来给类、对象、方法、变量、接口和自定义数据类型命名用的。
命名规则说明:
- 标识符可以由字母、数字、下划线(_)、美元符($)组成,但不包含@、#、空格等其他特殊字符,不能以数字开头。例如:1name 是不合法的。注意:Java标识符是可以允许中文命名的,因为Java内部使用了Unicode字符集。
- 标识符不能是Java关键字和保留字(Java预留的关键字,以后的Java升级版本中可能作为关键字),但可以包含关键字和保留字。例如:不可以使用 for 作为标识符,但是 myfor 是可以的。
- 标识符是严格区分大小写的,同时也没有长度的限制。例如:Myfor 和 myfor 是两个不同的标识符。
- 标识符的命名也不能随意而为,最好是能反映其作用的,做到看其名知其意。
Java语言中具有特殊用途的词,被称为关键字。Java中常用的关键字,如下所示:
abstract | extends | break | byte | case | catch |
char | class | continue | default | do | double |
else | if | boolean | false | true | public |
interface | long | int | float | short | void |
final | finally | try | for | static | this |
null | return | new | import | throw | throws |
switch | super | while | do | private | protected |
package | instanceof | native | implements | synchronized | volatile |
下面这个Java代码中的标识符,由于错误命名的标识符,导致这个Java文件不能编译成功,会直接报标识符相关的错误。
public class MyFirst { /**
* 错误命名的标识符
*/
String 1a = "test";
String u#a = "test";
String u@a = "test";
String void = "test";
String b a = "test"; /**
* 正确命名的标识符
*/
String _a = "test";
String $a = "test";
String aa = "test"; public static void main(String[] args) {
System.out.println("Hello World!");
} }
2 Java数据类型
Java是一种强类型语言,每一个变量都必须声明其类型。Java的数据类型分有两大类:基本类型(又称内置数据类型)和引用类型。
2.1 基本类型
Java提供了八种基本类型,其中有六种数字类型(四个整数型,long、short、int和byte,两个浮点型,float和double),一种字符型,char,还有一种布尔型,boolean。
2.1.1 整数型
byte
byte 数据类型是8位、有符号的,以二进制补码表示的整数,默认值是0,在Java中占用1个字节。
其可以以8位,即8个0、1表示。8位的第一位是符号位,即0000 0001表示数字1,1000 0000表示-1。所以其最大值是0111 1111,即127(2^7-1);最小值是1111 1111,即-128(-2^7)。从而可以知道,Java中一个byte字节的范围是-128~127。
例子:
byte a = 10;
byte b = -10;
注意:其他的整数型,如short、int和long,也是类似的用法,都可以以位数0、1表示,均有最大值和最小值,区别就是它们的位数不同。
short
short 数据类型是 16 位、有符号的,以二进制补码表示的整数,其默认值是0,在Java中占用2个字节。
其可以以16位,即16个0、1表示。最大值是32767(2^15 - 1),最小值是-32768(-2^15)。
例子:
short a = 10000;
short b = -10000;
int
int 数据类型是 32 位、有符号的,以二进制补码表示的整数,其默认值是0,在Java中占用4个字节。
其可以以32位,即32个0、1表示。最大值是2,147,483,647(2^31 - 1),最小值是-2,147,483,648(-2^31)。
例子:
int a = 1000;
int b = -1000;
long
long 数据类型是 64 位、有符号的,以二进制补码表示的整数,其默认值是0L,在Java中占用8个字节。
其可以以64位,即64个0、1表示。最大值是(2^63-1),最小值是(-2^63)。
注意:声明long类型,最好是后面加上“l”或“L”,例如:
long a = 10000000;//这样声明不会出错,因为在int数据类型的范围内(21亿内)
long b = 100000000000000;//这样就肯定会报错,因为已经超过了int的范围,必须改成100000000000000L才不会报错
2.1.2 浮点型
float
float 数据类型,又被称为单精度类型,是单精度、32位、符合IEEE 754标准的浮点数,尾数可以精确到7位有效数字,而最后一位第八位是存在舍入误差不精确的,其默认值是0.0f,在Java中占用4个字节。
float 数据类型的好处是在储存大型浮点数组的时候可节省内存空间,但是不能用来表示精确的值,如货币。
例子:
float f = 123.3f;
double
double 数据类型,又被称为双精度类型,是双精度、64 位、符合IEEE 754标准的浮点数,精确程度是float的两倍,即可精确到16位有效数字,而最后一位第17位是存在舍入误差不精确的,其默认值是0.0d,在Java中占用8个字节。
例子:
double d = 222.2;
注意:浮点数的默认类型为double类型,但是double 数据类型同样不能用来表示精确的值,如货币。如果需要精确的数字计算,可以使用BigDecimal类。
科学计数法
一种计数的方法,通常用来表示比较大的数据,其中的E或e,表示10的几次方。如,314e2,表示314 * 10^2,即31400;314e-2,表示314 * 10^-2,即3.14。
这种方法在Java中也是适用的。
float f = 314e-2f; // 314 * 10^-2
double d = 3.14e4; // 3.14 * 10^4
System.out.println(f); // 输出3.14
System.out.println(d); // 输出31400.0
2.1.3 字符型
char
char 类型是单一的16位Unicode字符,占2个字节,可以存储任何字符,最大值是 \uffff(即为65,535),最小值是 \u0000(即为0)。
例子:
char a = 'A';
注意:单引号是用来表示字符常量的,例如'A'是一个字符,它与"A"是不同的,"A"表示含有一个字符的字符串。
char类型是可以用来计算的,因为char在ASCII等字符编码表中是有对应的数值的。而在Java中的char类型字符运算时,是直接当做ASCII表对应的整数来对待的。
char a = 'A';
int b = 1;
int c = a+b;
System.out.println(c); // 输出66
Java语言中还允许使用转义字符'\'来将其后的字符转位其他的含义,例如,char c = '\n';//表示换行符
下面列举一些比较常见的转义符。
转义符 | 含义 | Unicode 值 |
\n | 换行 | \u000a |
\r | 回车 | \u000d |
\t | 制表符(tab键) | \u0009 |
\" | 双引号 | \u0022 |
\' | 单引号 | \u0027 |
\\ | 反斜杠 | \u005c |
2.1.4 布尔型
boolean 类型表示一位信息,注意不是一个字节。其只有两个值,true和false,默认值是false。
例子:
boolean a = true;
boolean 类型只是用来判断逻辑条件,一般用于if、while、do while。
2.2 引用类型
Java为每种基本类型都提供了对应的封装类型(即引用类型):Byte、Short、Integer、Long、Float、Double、Character和Boolean。引用类型就是一种对象类型,它的值是指向内存空间的引用,即类似于c语言中指针指向地址。其实这里的引用还跟变量、栈和堆是有关系的,但是这不是本节的关键,后续会有专门的一节来说明。
Java中的引用类型还分有四种,分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。其中,强引用是我们使用最普遍的引用,如果一个对象具有强引用,那垃圾回收器宁愿抛出OOM(OutOfMemoryError)也不会回收它。
强引用(StrongReference)
这种引用是平时开发中最常用的,例如 String strong = new String("Strong Reference") 。当一个实例对象具有强引用时,垃圾回收器不会回收该对象,当内存不足时,宁愿抛出OutOfMemeryError异常也不会回收强引用的对象,因为JVM认为强引用的对象是用户正在使用的对象,它无法分辨出到底该回收哪个,强行回收有可能导致系统严重错误。
软引用(SoftReference)
如果一个对象只有软引用,那么只有当内存不足时,JVM才会去回收该对象,其他情况不会回收。
如下例子,一般情况下内存充足的话,ss指向的对象是不会被回收,但是若内存不足则会把ss给回收掉。
Book ss = new Book("NONO");
SoftReference<Book> softReference = new SoftReference<>(ss);
ss = null;
System.gc();
System.out.println("对象是否被回收:"+softReference.get());
软引用可以结合ReferenceQueue来使用,当由于系统内存不足,导致软引用的对象被回收了,JVM会把这个软引用加入到与之相关联的ReferenceQueue中。
如下例子,当系统内存不足时,触发gc,这个Book就会被回收,但reference 将不会为null。
ReferenceQueue referenceQueue = new ReferenceQueue();
SoftReference<Book> softReference = new SoftReference<>(new Book(), referenceQueue);
Book book = softReference.get();
Reference reference = referenceQueue.poll();
弱引用(WeakReference)
只有弱引用的对象,当JVM触发gc时,就会回收该对象。与软引用不同的是,不管是否内存不足,弱引用都会被回收。弱引用可以结合ReferenceQueue来使用,当由于系统触发gc,导致软引用的对象被回收了,JVM会把这个弱引用加入到与之相关联的ReferenceQueue中,不过由于垃圾收集器线程的优先级很低,所以弱引用不一定会被很快回收。
虚引用(PhantomReference)
虚引用是所有类型中最弱的一个。一个持有虚引用的对象,和没有引用几乎是一样的,随时可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程。
当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,销毁这个对象,将这个虚引用加入引用队列。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
2.3 基本数据类型转换
2.3.1 自动类型转换
所谓自动类型转换,总结起来就是一句话,容量小的数据类型可以自动转换位容量大的数据类型。
例如,byte类型可以自动转换为其他容量比它大的数字类型(如int、short、float等等)。下面直接看一个实例,一切就清晰了。
public class MyFirst { public static void main(String[] args) {
byte a = 5;
short b = 5;
int c = 5;
long d = 5;
float e = 5.0f;
double f = 5.0; // 测试自动类型转换,容量最小的是byte,容量最大的是double,从小容量自动转换为大容量且不报错
double g = a + b + c + d + e + f;
System.out.println(g);
} }
若在上面的例子中,把最后的输出 g 的数据类型改为 float类型 float g = a + b + c + d + e + f; ,则肯定会编译不通过,报错 cannot convert from double to float 。
2.3.2 强制类型转换
强制类型转换,又称为显示类型转换,即在其值符合被强制转换的类型的情况下,我们可以将其强制转换为该类型。下面看个实例便清楚了。
public class MyFirst { public static void main(String[] args) {
int a = 5;
short b = (short) a;// 此处若没有(short)强制转换,则肯定会编译不通过的
System.out.println(b);
} }
我们再回到2.3.1看下这个例子,把 g 的数据类型改为 float类型 float g = a + b + c + d + e + f; ,其实这里就只是因为 f 是double类型,如果我们改成这样 float g = a + b + c + d + e + (float)f; ,将 f 的数据类型强制转换为float,程序就可以正常运行了。
其实强制类型转换,还包括了引用类型的强制转换,不过这里不说明,后面在讲类的继承和接口实现的时候会讲到。
2.4 Java字符串(String)
String是一个特殊的包装类数据,可以用 String str = new String("Java"); 的形式来创建,也可以用 String str = "Java"; 的形式来创建。但是,他们的创建过程是不一样的,下面具体说明下他们不一样的创建过程。
String str = "Java"; 的创建过程:首先在常量池中查找是否存在内容为"Java"的字符串对象;若不存在则会在常量池中创建一个"Java"的字符串对象,并让str引用该对象;若"Java"的字符串对象已经存在常量池中,则会直接让str引用该对象。
注意:常量池属于类信息的一部分,而类信息是存在于JVM内存模型的方法区,即常量池是存在于JVM的方法区的,当类编译时就会被分配到内存中。
String str = new String("Java"); 的创建过程:
(1)定义一个str的String类型的引用并存放在栈中;
(2)在字符串常量池中判断是否存在内容为"Java"的字符串对象,若不存在的话则在常量池中创建一个,若存在则不需要创建;
(3)执行new操作,在堆中创建一个指定的对象"Java",需要注意的是,这里堆的对象是字符串常量池中"Java"对象的一个拷贝对象;
(4)让str指向堆中的"Java"对象,即str存储的是堆中"Java"对象的地址。
下面举个例子,让我们看得更加通透。
public class MyFirst { public static void main(String[] args) {
String a = "Java";
String b = "Java";
String c = new String("Java");
String d = new String("Java");
System.out.println(a==b); // true 因为均是指向常量池中的同一个对象
System.out.println(a.equals(b));// true 因为他们的值相同
System.out.println(c==d); // false 因为他们在栈中存储的地址不一样,在堆中指向的对象也不一样
System.out.println(c.equals(d));// true 因为他们的值相同
} }
图解如下:
字符串的常用方法
返回类型 | 方法 | 说明 |
String | concat(String str) | 字符串的连接,将str字符串拼接到原来字符串的后面,并返回。 |
int | length() | 返回字符串的长度,这里的长度是指字符串中Unicode字符的数目。 |
char | charAt(int index) | 索引特定位置的字符,并返回该字符。 |
boolean | equals(Object anObject) | 字符串的比较,比较两个字符串的值是否相等,若相等则返回true,否则返回false。 |
int | compareTo(String anotherString) | 字符串的比较,比较两个字符串的值大小,若原有值大则返回大于0的整数,若原有值小则返回小于0的整数,若他们相等则返回0。 |
String |
substring(int beginIndex) substring(int beginIndex, int endIndex) |
从字符串中截取子字符串,从beginIndex位置起,到endIndex位置为止,但不包括endIndex位置的字符,截取子字符串,返回子字符串。 |
int |
indexOf(int ch) indexOf(int ch, int fromIndex) indexOf(String str) indexOf(String str, int fromIndex) |
从字符串中获取对应字符第一次出现的位置,若整个字符串都没有该字符,则返回-1。 |
String |
trim() |
去除原字符串的前后空格并返回。 |
下面看下这些常用方法对应的例子。
public class MyFirst { public static void main(String[] args) {
String a = "I like Java ";
String b = "very much!";
System.out.println(a.concat(b));// a和b字符串的拼接,输出:I like Java very much! String c = "abc123";
System.out.println(c.length());// c字符串的长度,输出:6
System.out.println(c.charAt(2));// 索引c字符串中的2位置的字符,输出:c
System.out.println(c.substring(2));// 截取从2位置开始到结尾的字符串,输出:c123
System.out.println(c.indexOf("b"));// 获取字符为b的第一次出现的位置,输出:1 String d = "Java";
String e = "Java";
String f = "Java1";
System.out.println(d.equals(e));// 比较d和e的值,输出:true
System.out.println(d.equals(f));// 比较d和f的值,输出:false
System.out.println(d.compareTo(e));// 比较d和e的值,输出:0
System.out.println(d.compareTo(f));// 比较d和f的值,输出:-1 String g = " asdfgh ";
System.out.println(g.trim());// 去掉g的前后空格,输出:asdfgh
} }
3 总结
- Java标识符的命名,以及Java关键字。
- Java数据类型,分有基本类型和引用类型。
- 基本类型,有六种数字类型(四个整数型,long、short、int和byte,两个浮点型,float和double),一种字符型,char,还有一种布尔型,boolean。
- 引用类型,有强引用、软引用、弱引用和虚引用,其中我们平常普遍用到的就是强引用。
- 基本数据类型转换,有自动类型转换和强制类型转换。
- String字符串,一种特殊的包装类数据。
基础篇-1.2Java世界的规章制度(上)的更多相关文章
- 基础篇-1.2Java世界的规章制度(下)
1 Java运算符 Java世界中的运算其实就是数学运算,而运算符就是其中的媒介. 算术运算符 操作符 描述 + 加法,对符号两边的数值相加 - 减法,符号左边的数减去右边的数 * 乘法,符号两边的数 ...
- 《量化投资:以MATLAB为工具》连载(1)基础篇-N分钟学会MATLAB(上)
http://blog.sina.com.cn/s/blog_4cf8aad30102uylf.html <量化投资:以MATLAB为工具>连载(1)基础篇-N分钟学会MATLAB(上) ...
- 一、基础篇--1.2Java集合-HashMap和ConcurrentHashMap的区别【转】
http://www.importnew.com/28263.html 今天发一篇”水文”,可能很多读者都会表示不理解,不过我想把它作为并发序列文章中不可缺少的一块来介绍.本来以为花不了多少时间的,不 ...
- 一、基础篇--1.2Java集合-HashMap源码解析
https://www.cnblogs.com/chengxiao/p/6059914.html 散列表 哈希表是根据关键码值而直接进行访问的数据结构.也就是说,它能通过把关键码值映射到表中的一个位 ...
- 一、基础篇--1.2Java集合-Arraylist 与 LinkedList 区别
Arraylist 与 LinkedList 区别 结构上的区别 ArrayList底层实现基于动态数组,LinkedList底层实现基于双向链表. 性能上区别 ArrayList查询快,增删慢 ...
- 一、基础篇--1.2Java集合-HashMap死循环问题
为什么HashMap会出现死循环 首先,我们知道java的HashMap不是线程安全的.多线程下应该使用ConcurrentHashMap. HashMap底层是基于动态数组和单向链表(JDK1.7, ...
- 一、基础篇--1.2Java集合-HashMap和HashSet的区别
HashMap和HashSet的区别 1.HashMap实现的是Map接口,HashSet实现的是Set接口 2.结构不一样,一个存储的是键值对,一个存储的是对象 3.HashMap存储的值可能相同 ...
- 一、基础篇--1.2Java集合-HashMap和HashTable的区别
HashMap和HashTable的区别 1.继承的父类不同,HashMap继承的是AbstractMap类,HashTable继承的是Dictionary类,不过都实现了Map.Clone.Seri ...
- 一、基础篇--1.2Java集合-ArrayList和Vector的区别
ArrayList和Vector的区别 ArrayList和Vector都是基于动态数组实现的. 区别 ArrayList是非线程安全的,Vector是线程安全的. Vector的方法都加了同步锁 ...
随机推荐
- LOCK_TIMEOUT
SET LOCK_TIMEOUT 1000 begin tran TranNameA select * from tablenameA WITH (updlock) where... waitfor ...
- DELPHI编写服务程序总结(在系统服务和桌面程序之间共享内存,在服务中使用COM组件)
DELPHI编写服务程序总结 一.服务程序和桌面程序的区别 Windows 2000/XP/2003等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...
- HTTP 错误 403.14 - Forbidden Web 服务器被配置为不列出此目录的内容。
解决方法: 找到目录浏览,打开,点击右边的启用就OK了.
- C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型
原文:C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型 线程模型 SocketAsyncEventArgs编程模式不支持设置同时工作线程个数,使用的NET的IO ...
- Delphi使用TObject类对象创建接受window消息(使用Classes.AllocateHWnd为对象创建一个尺寸为0的窗口,从而有了Handle)good
在delphi中,有时候我们希望对象可以接收windows消息,怎么办呢?因为要接收windows消息起码要有windows Handle,难道要建立的一个可见窗口?那样似乎太差强人意了.delphi ...
- 全量导入数据 导致solr内存溢出 崩溃问题解决
在 data-config.xml 文件中 增加一个参数即可: batchSize="-1"
- Spring Type Conversion(Spring类型转换源码探究)
1:概述 类型转换系统负责Spring框架中对象类型转换和格式化工作. ConversionService默认实现UML图如下所示: GenericConversionService(通用类型转换服务 ...
- RocketMQ(1)-架构原理
RocketMQ(1)-架构原理 RocketMQ是阿里开源的分布式消息中间件,跟其它中间件相比,RocketMQ的特点是纯JAVA实现:集群和HA实现相对简单:在发生宕机和其它故障时消息丢失率更低. ...
- 304902阿里巴巴Java开发手册1.4.0
转自官网 前言 <阿里巴巴Java开发手册>是阿里巴巴集团技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断完善,系统化地整理成册,回馈给广大开发者.现代软件行业的高速 ...
- Alwayson架构下 服务器 各虚拟IP漂移监控告警的功能实现
1.需求概括 我们知道,在SQL Server Alwayson 架构中,有多种虚拟IP,例如 WindowsCluster IP,ListenIP,角色高可用性IP(类似于侦听IP).在某些条件下, ...