方法 | 分隔符 | 浮点型 | 整型 | 编码惯例 | 数据存储细节 | 我的博客 | |
变量 | 语句块 | 字符型 | 关键字 | 标准输入输出 | 对象构造和初始化 | v512工作室 | |
值传递 | 标识符 | 布尔型 | 数据类型 | 引用数据类型 | 形式参数和实参及返回值 | 中科院新科海学校 |
注释
概述:注释(Comment)是对源程序起解释说明作用的文本信息,适当使用注释能够增强代码的可读性
Java语言中定义了三种注释形式://单行注释---注释到行尾
/*单行或多行注释*/
/**可用于文档化处理的单行或多行注释*/
文档:在自定义类中public的成员前以/**...*/形式加入的注释内容均可被自动提取到生成的说明文档中
JDK中提供了一个文档自动生成工具javadoc,用法为javadoc source.java
说明:javadoc默认只提取public类、public方法、public属性前的文档化注释内容
这只是javadoc基本用法,它还有很多参数以及非常复杂的用法。直接在命令提示符窗口输入javadoc回车后即可查看
分隔符
组成:分号“;”、逗号“,”、空格“ ”、圆点“.”、花括号“{”及“}"
作用:Java语句必须以分号作为结束标记,for循环语句中使用分号来分隔不同的成员
逗号可以在方法声明或强调时的参数列表中用于分隔多个参数,也可在一条声明语句中同时声明多个属性或局部变量时起分隔作用
Java程序源代码中各组成部分之间可以插入任意数量的空格,包括换行
圆点用于访问对象成员,即属性或方法时标明调用或隶属关系,其格式为“对象名.对象成员”
花括号用于构造语句块
举例:private int i;
private int j;//这两行其实就可以写成private int i,j;
语句块
概述:Java允许用花括号“{}”将一组语句括起来形成一个语句块(block)
用法:定义类时,类体必须采用语句块形式
定义方法时,方法体必须采用语句块形式
定义循环语句时,循环体可以采用语句块的形式,采用将零到多条语句集合到一起,作为一个整体进行处理
语句块可以嵌套,嵌套层数无限制
标识符(identifier)
概述:Java语言中为各种变量、方法和类等起的名字称为标识符
命名:应以字母、下划线、美元符开头
后跟字母、下划线、美元符或数字
Java标识符大小写敏感,长度无限制
用法:合法:HelloWorld、DataClass、_983、$bS5_c7
非法:class、DataClass#、98.3、Hello World
关键字(keyword)
Java语言中一些被赋以特定的含义、并用做专门用途的单词称为关键字
所有Java关键字都是小写的。如TURE、FALSE、NULL等都不是Java关键字
虽然goto和const在Java中暂时没有被使用,但也被作为Java关键字保留,所以二者不能用作标识符
true、false虽然不是Java关键字,但被用作专门用途了,所以也不能用作标识符
数据类型
概述:数据类型就是一组性质相同的值得集合以及定义于这个值集合上的一组操作的总称
高级编程语言:可分为强类型语言(Strong Typed Languages)和弱类型语言(Weakly Typed Languages)
强类型语言要求每个变量都要有固定的数据类型,而弱类型语言变量的类型是可以变化的
这是按照对数据类型的使用约束程度来划分的。JavaScript就是弱类型语言,而C、C#、C++、Java皆为强类型语言
基本数据类型:基本类型(Primitive Type)的数据只能保存单一的值,因此也被称为原始类型或单类型
Java中定义了四类/八种基本数据类型
逻辑型——boolean
文本型——char
整数型——byte、short、int、long
浮点型——float、double
整型
概述:整型数据用于保存整数信息,Java提供了四种不同的整数类型
各有固定的表数范围和字段长度,而不受具体操作系统的影响,以保证Java程序的可移植性
常量:十进制整数。如12、-314、0
八进制整数,要求以0开头。如012
十六进制整数,要求0x或0X开头。如0x12(以零X开头)
说明:Java语言的整型常量默认为int型。如要声明long型可以在常量后面加“l”或“L”(一般为了区分l和1,我们都使用L作为long型标识)
举例:int a=39; int b=0x4b; int c=021;
int d=a+0x12+012; //等价于d=39+10+18;
long m=3L;
long n=m+40;
浮点型
概述:Java浮点型包括float和double两种,分别用于保存单精度和双精度的浮点数。浮点型同样有固定的字段长度和表数范围
常量:十进制——必须含有小数点,也可采用科学计数法表示。如3.65、0.12、.12、4.236e2、4.5E-3
十六进制—从JDK5.0开始引入,十六进制浮点数只能采用科学计数法表示
其格式为:<0x|0X><十六进制尾数><p|P><以2为底的指数>
例如0x1.2p3,转换为十进制的计算方法为:0x1.2p3=[1*1+2*(1/16)]*8=9.0
说明:Java浮点型常量默认为double型。如要声明float型常量,则需在数字后面加“f”或“F”
例一:float d=9.42; //报错 //因为9.42没有加F标识,那么9.42就是为默认的double型,而double是不能赋给float型的
long n=5; //通过 //因为double表示数的范围要大于float型,这点跟整型里的long和int间是不同的。这里就需要做强制类型转换
float f=6.28f; //通过 //强制类型转换:float f=(float)9.42;(其中“(float)”表示的是强制转换以后的类型)
例二:double c1=0.0/0.0; //输出NaN(表示不是一个数,即Not a Number)
double c2=0.0/3.0; //输出0.0
double c3=3.0/0.0; //输出Infinity(表示正无穷大)
double c4=-3.0/0.0; //输出—Infinity(表示负无穷大)
字符型
概念:字节、字符、字符集、字符编码。Java语言采用16位Unicode编码保存
char型数据用来表示通常意义上的字符,这里表示的只是一个字符,而不是字符串
常量:使用单引号括起来的单个字符。例如:char c='A';
十六进制Unicode编码形式表示。例如:char c1='\u0061';\u表示它后面的数字代表的是一个十六进制的Unicode编码
使用转义字符‘\’来将其后的字符转变为其它的含义。例如:char c2='\n';//代表换行符
举例:char c2='\u0061'; //输出a
char c4='\\'; //输出\
char c5='\t'; //输出一个Tab键效果
布尔型
boolean型数据用来表示只有两种状态的逻辑值,分别代表现实生活中的特定条件成立与否,通常用于逻辑运算和程序流程控制
boolean型数据只允许取值true或false。不可以用0或非0的整数替代true和false。这是C/C++中的做法,但在Java中是不允许的
引用数据类型(Reference Type)
概述:Java语言中除八种基本数据类型以外,其它的数据类型统称为引用类型。具体包括:类、接口、数组、枚举和注解类型
引用类型数据以对象的形式存在。引用类型变量的值是某个对象的句柄,而不是对象本身
声明引用类型变量时,系统只为该变量分配引用空间,并未创建一个具体的对象
引用类型同基本数据类型相比,它的创建和声明都是比较复杂的一个过程
举例:public class MyDate{private int day = 17;private int month = 2;private int year = 2007;
public MyDate(){}public MyDate(int d,int m,int y){day = d; month = m; year = y;}
public void setDay(int d){day = d;}public intgetDay(){return day;}
public void setMonth(int m){month = m;}public intgetMonth(){return month;}
public void setYear(int y){year = y;}public intgetYear(){return year;}
public void display(){System.out.println(year + "-" + month + "-" + day);} }
public class TestReferenceType{public static void main(String args[]){
MyDate d1; //声明了一个MyDate类型的变量d1,那么d1就是一个引用类型的变量
d1 = new MyDate(8,8,2008); //它保存的值是一个对象的地址值或者说句柄、引用。d1可以叫做引用,也可以叫做句柄
d1.display();}} //新建的MyData类型对象的地址值赋给了d1。d1的值实际保存的是对象的引用或者说对象的地址
对象构造和初始化
一、为引用类型变量分配引用空间
语句:MyDate d1;
内存状态:声明一个MyDate类型变量d1,这时内存会为d1分配一个32位定长的引用空间。但空间里没有任何的值
所有的引用类型的变量都是定长的,都是4个字节32位的引用空间
二、创建新对象并为其分配内存空间和进行属性(实例变量)的默认初始化
语句:d1=new MyDate(8,8,2008);
内存状态:先创建一个MyDate类型的对象,再把这个对象的值赋给d1。创建新对象也要经历一些过程
首先要为新对象分配内存空间,并且进行属性或者说实例变量的默认初始化
也就是说创建这个对象的时候,先为它开辟一个空间,然后对它的三个属性进行默认初始化
初始细节:事实上,一个对象一经创建,系统就立即将它所有的内存空间都清零,就实现了对象的初始化
即全部都是二进制的0。如果把它转换成十进制,结果还是0。如果是boolean类型,初值自然也就是false了
当对象是引用类型的时候,它的内存空间也都是二进制的0,等于什么都没有,那它的初值自然也就是null了
也就是说,这一切都是约定好的,对象创建后,它的内存中全部都情空成二进制的0,通过这种方式实现了初始化
所以说默认初始化实施起来很简洁,不得不佩服sun的人
三、进行属性的显式初始化,显式初始化取值来自于类的定义中属性声明部分
语句:private int day=17; private int month=2; private int year=2007;
内存状态:显式初始化就是说这个类中定义的三个属性,它是有默认值的(分别为17,2,2007)
所以原来的三个属性值分别都是0,现在变成了17,2,2007
注意:如果属性在声明时未指定缺省值,则在这个环节就不对其进行赋值操作
四、执行构造方法体中的语句
语句:public MyDate(int d,int m,int y){day = d; month = m; year = y;}
内存状态:这时该对象的三个属性的值又变了,变成8,8,2008
注意:此时新建对象和先前声明的变量d1间还是没有建立任何关联
五、为引用类型变量赋值
语句:d1 = new MyDate(8,8,2008);
内存状态:相当于把MyDate对像的地址值赋给d1,所以d1的存储空间中保存的只是MyDate对象的地址值而不是它所有的属性值
将来如果想通过d1调MyDate对象的方法的时候,根据d1地址值就能找的MyDate对象所对应的属性的值
说明:此时变量d1保存的并不是新建对象封装的具体信息(如属性值等),而是该对象的句柄(Handle)
所以可以把d1叫做句柄或者引用。句柄可以理解成是对象的内存存储地址
变量d1有点像环境变量path,path中记录的并不是真正的JDK中所有的工具,而是工具文件的存储路径
总结:d1记录了MyDate对像的存储地址。d1指向了一个MyDate类型的对象,类似于C语言中的指针
d1引用了一个对象。d1代表了一个对象。通过d1能够操纵一个对象
六、补充:这时d1.display()的准确说法是:引用类型的变量d1当前所引用的的对象,就是它所指向的那个对象
就是它所记录的那个内存地址所保存的对象,调用了dispaly()方法
变量和对象是有差异的,d1只是一个变量,只占32bit的空间,它保存的不是真正的信息,而是信息的存储地址
对象实际占有的内存空间要比它所有的属性占有的内存空间的总和还要多一些
因为对象本身还携带了它所属类型的信息(就是类名)和类的版本号等信息
d1相当于C语言中的指针,d1记录的是一个对象的地址,我们称之为一个对象的句柄
我们把变量和对象之间的这种关系称之为引用关系,所以称d1为引用类型的变量,称MyDate为引用数据类型
所以引用数据类型也称为复杂的数据类型或构造类型
七、扩展:如果再执行一个MyDate d2 = d1;的话,内存中的状态是,首先会为d2分配32位定长的引用空间
然后将d1的值(这个值是句柄,是内存地址,不是对象本身)复制给d2。即变量之间赋值永远是值传递
如果再执行d2.setYear(3008);是指引用类型变量d2当前所引用(指向)的MyDate对象调用其setYear()方法修改其属性year为3008
八、纠正:引用类型变量d1记录的值,并不是所引用对象的内存首地址。变量d1记录的是对象的句柄,它是基于内存地址进行换算的
对象一经创建,JVM中通常是对这个对象的内存地址,包括硬盘上的物理存储路径
进行了哈希散列,也就是进行了哈希映射。说白了就是转换。但结果还是一个整数
所以说,它不是内存地址,而是一个基于内存地址的哈希散列。实际上也叫哈希码
九、哈希:哈希映射就好似编码的机器。即任何两个不同的输入,都一定会导致两个不同的输出
任何相同的输入,都会有相同的输出。这种哈希散列的算法可以理解成是加密和解密
所谓的安全性连接SSL的方式,就是先对要发送的数据(如22)进行哈希映射(即加密)
即调用哈希方法把22转换成128位或更长的值,接收时可以逆向转换,最终还原成22
这个过程就叫做哈希散列。外人无法破解这种算法。比如发送手机号时也可以用到它
十、附加:两行代码int i=5;和int j=i;执行之后的内存状态:先为i分配一个32位空间,并赋上表示5的一系列的二进制数
然后也要为j分配一个32位的空间,再把内存中i的存储空间中的值(表示5的一系列二进制数)复制到j的存储空间中
接着i和j就没有关系了。比如再执行一个int j=6;但是i还是等于5。即两个变量占有两个不同的空间,都保存单一的值
这就是基本类型之间的赋值,这也是下面要学到的值传递
方法(Method)
概述:方法是类的动态性能,描述了该类事物所共有的功能或行为
Java语言的方法相当于其它编程语言中的函数(Function)或子程序(Subroutine),是用来完成相对独立功能的一段代码的集合
规则:方法必须定义在类中而不允许直接出线在源文件内
只有其所在类的对象才有资格调用方法
方法的定义不允许出现嵌套
形式参数和实参及返回值
形参:在方法被调用时用于接收外界输入的数据
实参:调用方法时实际传给方法的数据
返回值:方法在执行完毕后返还给调用它的环境的数据
返回值类型:事先约定的返回值的数据类型
如无返回值,在Java中也必须给出返回值数据类型为void。定义构造方法时则不允许给出返回值类型
相关语法:形参列表格式:(数据类型1 参数名1,数据类型2 参数名2,...)
实参列表格式:(参数1,参数2,...)
Java语言中使用下述形式调用方法:对象名.方法名(实参列表)
实参可以是变量、常量或表达式,但其数目、类型和出现的顺序必须和相应的形参保持一致,此称为参数匹配
return用于终止方法的运行并指定要返回的数据。若方法的最后一行没有return语句,则编译时系统会自动添加return;
变量(Variable)
概述:用于记录数值可以改变的数据。计算机技术中变量包括变量名和变量值两部分
变量名——用于标记一段特定的存储空间
变量值——以二进制形式保存在该空间中且可以被访问和修改
分类:所属数据类型划分:基本类型变量和引用类型变量
按声明的位置划分:局部变量——方法或语句块内部定义的变量
成员变量——方法外部或类的内部定义的变量
作用域:成员变量的作用域与其所属对象的作用域相同
局部变量的作用域就是它所在的方法或语句块
生存期:成员变量的生存期与其所属的对象相同,随着对象的创建而创建,随对象的销毁而销毁
局部变量的生存期就是其所在方法或语句块单次执行的期间
即在程序每一次调用方法或运行进入到一个语句块中时,其中的局部变量才被创建并可用。随方法或语句块的退出,局部变量将被销毁
声明和初始化:Java语言中变量必须先声明和初始化(赋初值)然后才可以使用
成员变量在类的定义中声明。创建对象的同时创建有关的成员变量,然后由系统自动对其默认初始化和显式初始化
局部变量声明语法格式:<类型> <变量名1>[=<缺省值1>][,<变量名2>[=<缺省值2>]...];
举例:public void m1(int a,int b){int i;
int j=i+4; //编译出错,因为变量i尚未初始化
int k=a+b;} //形参属局部变量,方法调用时会被隐含的初始化
数据存储细节
概述:计算机的物理内存在OS和JVM中使用时分为堆内存和栈内存两种方式
Java程序运行时,局部变量保存在栈内存中,而对象及其成员变量保存在堆内存中
细分:堆内存(Heap Memory)由所有的应用程序公用,存储空间分配不连续,存储容量大。在堆内存中分配存储空间和进行存取操作速度较慢
栈内存(Stack Memory)由特定应用程序专用,存储空间是连续的,以栈的方式(后进先出)进行管理,存储容量小,但访问速度快
值传递(Pass By Value)
Java语言中进行赋值操作或函数调用中传递参数时,遵循值传递的原则,即传递的永远是参数的值
关于值传递的详细讲解,在教程中第03章Java基础语法的02:07:26←→02:08:54←→02:19:30中
Java值传递分为两种不同情形:基本类型数据传递的是该数据的本身
引用类型数据传递的是对象的引用(句柄,或者说是对象的地址值)而非对象本身
标准输入输出
控制台Console:之前练习的程序实际上都是控制台程序,就是通过DOS终端窗口输出一些内容
那么我们也同样可以通过终端窗口接收用户输入的一些内容。在JDK5.0以后特别增加了一个Scanner类
利用这个类就可以非常方便的读取用户在控制台程序中输入的内容。Scanner类位于Java的util包中
读取控制台输入:Scanner s=new Scanner(System.in); //用法:首先生成Scanner类的一个对象s,但new Scanner()中需要有一个参数
String name=s.nextLine(); //我们这里传的是System.in属性的值。实际上这里对应的是一个对象
int age=s.nextInt(); //这个对象就代表当前系统的输入设备。那么这里System.in代表的就是键盘
double salary=s.nextDouble(); //也就是说生成一个Scanner对象s,s可以读取用户在终端程序当中通过键盘输入的字符
格式化输出:System.out.printf() //那么输入的内容都传递给了s对象。我们就可以使用类似于nextLine等方法读取用户的输入
控制台输入例子:import java.util.Scanner;public class TestInput{public static void main(String args[]){Scanner s = new Scanner(System.in);
System.out.println("请输入你的姓名:");String name = s.nextLine();
System.out.println("请输入年龄:");int age = s.nextInt();
System.out.println("请输入你的工资数额:");double salary = s.nextDouble();
System.out.println("您的个人信息:\n姓名:" + name + "\t年龄:" + age + "岁\t工资:" + salary + "元");}}
格式化输出例子:public class TestPrintf{public static void main(String args[]){
System.out.printf("%+8.3f", 3.14); //输出+3.140
System.out.printf("%+-8.3f\n", 3.14); //输出+3.140
System.out.printf("%08.3f\n", 3.14); //输出0003.140
System.out.printf("%(8.3f\n", -3.14); //输出(3.140)
System.out.printf("%,f\n", 2356.34); //输出2,356.340000
System.out.printf("%x\n", 0x4a3b); //输出4a3b
System.out.printf("%#x\n", 0x4a3b); //输出0x4a3b
System.out.println("----------------"); //输出----------------
System.out.printf("你好:%s,%3d岁,工资%-7.2f\n", "张三",38,15000.00); //输出你好:张三, 38岁,工资15000.00
System.out.printf("你好:%1$s,%2$3d岁,%2$#x岁\n", "张三",38); //输出你好:张三, 38岁,0x26岁
System.out.printf("%3d,%#<x",38);}} //输出38,0x26
随着Java程序的开发,平时很少使用Java开发类似于这样的终端程序。所以该终端下的这种格式化输出就更少见了
关于格式化输出的例子,在教程中第03章Java基础语法的02:44:25—02:56:28中有详细讲解
编码惯例
概述:编码惯例是指开发人员在编码过程中应遵循的约定:命名惯例、文件组织、分隔和缩进
以下为Sun公司推出的编码惯例。一般来说,接口名和类名都会用到名词性质的单词,方法名用动词性质的单词
命名管理:包名:package com.domain;(小写的单个单词。如果公司有域名的话,包名书写要与域名顺序相反。如package com.v512;)
类名:class SprintRain;(由一个单词或多个单词组成,每个单词的首字母大写。两个单词直接连接,不要有下划线)
接口名:interface Account(无论由几个单词组成,其首字母都要大写)
方法名:modifyAccount()(一个单词时,首字母小写。多个单词时,第一个单词小写,后面每个单词的首字母都要大写)
变量名:studentName(同方法名的命名规则一致)
常量名:MAX_LEVEL(单词全部大写。如果由多个单词组成,那么单词间用下划线连接)
文件组织:Sun的推荐顺序为:属性声明——构造方法声明——static语句——普通方法声明——main方法声明——内部类的声明
分隔缩进:使用空行:一般在方法之间空一行———在方法内部代码的逻辑段落小节之间———在方法中声明局部变量之后,具体的Java语句之前
在注释行之前———在同一个源文件中定义的多个类或接口之间使用双行的空白行来分隔
使用空格符:运算符和运算符之间,如:c = a + b;———在参数列表中的逗号后面,如void m1(int year, int month){}
使用换行符:int i = 5; int k = 6; k = k + i;
int i = 5;
int k = 6;
k = k + i;
使用小括号:if (a == b && c == d % 10)//避免———if ((a == b) && (c == (d % 10)))//提倡
使用花括号:在使用花括号时,其开始位置可以位于当前内容的尾部(本行的行尾),也可另起一行,结束位置应与其成份的开始字母处于同一列
使用缩进:类中的成份———方法体或语句块中的成份———换行时的非起始行———缩减量一般为在上一级成份的基础上再缩进四个空格
声明语句:建议每行声明一个变量,并尽量在声明变量的同时对其进行初始化,除非其初值尚不确定
局部变量应在其所在的方法或语句块的开头集中声明,而不应随用随声明
也应避免将变量不必要地声明在外层范围中,否则会影响代码的可读性
其他:代码应永远力求简洁
if(booleanExpression){
return true;
}else{
return false;
} //不推荐
return booleanExpression; //推荐