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. 基础篇-1.2Java世界的规章制度(下)

    1 Java运算符 Java世界中的运算其实就是数学运算,而运算符就是其中的媒介. 算术运算符 操作符 描述 + 加法,对符号两边的数值相加 - 减法,符号左边的数减去右边的数 * 乘法,符号两边的数 ...

  2. 《量化投资:以MATLAB为工具》连载(1)基础篇-N分钟学会MATLAB(上)

    http://blog.sina.com.cn/s/blog_4cf8aad30102uylf.html <量化投资:以MATLAB为工具>连载(1)基础篇-N分钟学会MATLAB(上) ...

  3. 一、基础篇--1.2Java集合-HashMap和ConcurrentHashMap的区别【转】

    http://www.importnew.com/28263.html 今天发一篇”水文”,可能很多读者都会表示不理解,不过我想把它作为并发序列文章中不可缺少的一块来介绍.本来以为花不了多少时间的,不 ...

  4. 一、基础篇--1.2Java集合-HashMap源码解析

    https://www.cnblogs.com/chengxiao/p/6059914.html  散列表 哈希表是根据关键码值而直接进行访问的数据结构.也就是说,它能通过把关键码值映射到表中的一个位 ...

  5. 一、基础篇--1.2Java集合-Arraylist 与 LinkedList 区别

     Arraylist 与 LinkedList 区别  结构上的区别 ArrayList底层实现基于动态数组,LinkedList底层实现基于双向链表.  性能上区别 ArrayList查询快,增删慢 ...

  6. 一、基础篇--1.2Java集合-HashMap死循环问题

    为什么HashMap会出现死循环 首先,我们知道java的HashMap不是线程安全的.多线程下应该使用ConcurrentHashMap. HashMap底层是基于动态数组和单向链表(JDK1.7, ...

  7. 一、基础篇--1.2Java集合-HashMap和HashSet的区别

     HashMap和HashSet的区别 1.HashMap实现的是Map接口,HashSet实现的是Set接口 2.结构不一样,一个存储的是键值对,一个存储的是对象 3.HashMap存储的值可能相同 ...

  8. 一、基础篇--1.2Java集合-HashMap和HashTable的区别

    HashMap和HashTable的区别 1.继承的父类不同,HashMap继承的是AbstractMap类,HashTable继承的是Dictionary类,不过都实现了Map.Clone.Seri ...

  9. 一、基础篇--1.2Java集合-ArrayList和Vector的区别

     ArrayList和Vector的区别 ArrayList和Vector都是基于动态数组实现的.  区别 ArrayList是非线程安全的,Vector是线程安全的. Vector的方法都加了同步锁 ...

随机推荐

  1. LOCK_TIMEOUT

    SET LOCK_TIMEOUT 1000 begin tran TranNameA select * from tablenameA WITH (updlock) where... waitfor  ...

  2. DELPHI编写服务程序总结(在系统服务和桌面程序之间共享内存,在服务中使用COM组件)

    DELPHI编写服务程序总结 一.服务程序和桌面程序的区别 Windows 2000/XP/2003等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...

  3. HTTP 错误 403.14 - Forbidden Web 服务器被配置为不列出此目录的内容。

    解决方法: 找到目录浏览,打开,点击右边的启用就OK了.

  4. C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型

    原文:C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型 线程模型 SocketAsyncEventArgs编程模式不支持设置同时工作线程个数,使用的NET的IO ...

  5. Delphi使用TObject类对象创建接受window消息(使用Classes.AllocateHWnd为对象创建一个尺寸为0的窗口,从而有了Handle)good

    在delphi中,有时候我们希望对象可以接收windows消息,怎么办呢?因为要接收windows消息起码要有windows Handle,难道要建立的一个可见窗口?那样似乎太差强人意了.delphi ...

  6. 全量导入数据 导致solr内存溢出 崩溃问题解决

    在 data-config.xml 文件中 增加一个参数即可: batchSize="-1"    

  7. Spring Type Conversion(Spring类型转换源码探究)

    1:概述 类型转换系统负责Spring框架中对象类型转换和格式化工作. ConversionService默认实现UML图如下所示: GenericConversionService(通用类型转换服务 ...

  8. RocketMQ(1)-架构原理

    RocketMQ(1)-架构原理 RocketMQ是阿里开源的分布式消息中间件,跟其它中间件相比,RocketMQ的特点是纯JAVA实现:集群和HA实现相对简单:在发生宕机和其它故障时消息丢失率更低. ...

  9. 304902阿里巴巴Java开发手册1.4.0

    转自官网 前言 <阿里巴巴Java开发手册>是阿里巴巴集团技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断完善,系统化地整理成册,回馈给广大开发者.现代软件行业的高速 ...

  10. Alwayson架构下 服务器 各虚拟IP漂移监控告警的功能实现

    1.需求概括 我们知道,在SQL Server Alwayson 架构中,有多种虚拟IP,例如 WindowsCluster IP,ListenIP,角色高可用性IP(类似于侦听IP).在某些条件下, ...