第二章 Java基本语法
注释
分类
-
单行注释
//,单行注释:不参与编译; 注释就是说明性文字, 不参与程序的任何执行, 编译器javac 在编译这个源文件时, 会直接丢弃所有注释
如下的main方法是程序入口
main的格式是固定的
-
多行注释
/*
多行注释有开始, 有结束, 便于找到它的范围 我也是注释... 用多注释可以帮助我们更清晰的阅读程序 多行注释不可以嵌套
*/
3.文档注释
/**
*/
单行注释和多行注释作用
-
对所写的程序进行进行解释说明,增强可读性,方便自己,方便别人
-
调试所写代码
特点
单行注释和多行注释,注释了的内容不参与编译。
换句话说,编译以后生成的.class结尾的字节码文件中不包含注释掉的信息
文档注释
特点:注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的的说明文档。
-
主类、非主类 公共类、非公共类
/*
public : 公共的, 是形容词, 用于修饰类, 也可以修饰方法或属性, 称为修饰符
class : 类的意思, 用于定义一个类
Hello : 是类的名称, 随便写的.
类名后面的一对{} 表示一个范围, 这是类的定义的实体范围 称为类体 (body)
类 = 类头(类签名,是类的说明) + 类体(类的主体);
类是java程序的最基本单位. 一个程序至少是需要一个类的.
主类 : 包含了主方法的类.
非主类 : 不包含主方法的类.
公共类 : 有public修饰的类. 公共类的类名必须要和文件名一致, 所以一个源文件中, 最多只能有一个公共类.
非公共类 : 没有public修饰的类. 类名可以随便
*/
public class Hello {
/*
方法(method) : 是java程序中的一个独立的功能单位, 可以多次使用.
方法隶属于类, 决不可以把方法放在类的外面, 方法不可以嵌套方法
public static 是修饰符, 表示这是一个公共的静态的方法.
参数后面的一对{} 表示的是方法的主体 (方法体 )
方法 = 方法头(方法签名, 是方法的说明) + 方法体;
下面的方法称为主方法, 主方法也称为入口方法, 主方法写法固定, 必须 记死
*/
public static void main(String[] args) {
// 语句(statement) : 是java程序的最小执行单位. 真正执行的代码, 必须要以;结尾
// 语句会编译成指令, 由JVM执行的指令.
// 语句必须隶属于方法, 不可以写在方法外面.
System.out.println("这是字符串, 这里可以随便写, 这是我的第一个java程序, 准备受死吧");
System.out.println("我又是一行2");
System.out.println("我又是一行3");
//System.out.println("我又是一行4");
//System.out.println("我又是一行5");
}
public static void test() {
System.out.println("test()...");
}
/* 一个类中方法不能重复定义.
public static void main(String[] args) {
System.out.println("Hello main2...");
}
*/
}
// 非主类
// 非公共类
class Hello2 {
public static void test2() {
System.out.println("Hello2 test2()...");
}
}
// 主类
// 非公共类
class Hello3 {
public static void main(String[] args) { // 这是可以的, 因为这个主方法隶属于Hello3
System.out.println("Hello3 main()...");
}
}
class class2 {
}
关键字:
有特殊用途和含义的单词
保留字:
目前不是关键字, 将来有可能是关键字
写类名, 避免使用以上的.
标识符:
标识符:凡是自己可以起名字的地方都叫标识符 比如:类名、变量名、方法名、接口名、包名...
命名规则:必须遵守
1)组成: 52个字母, 0~9数字字符. _和$(不建议使用), -- 汉字更不建议使用. 比如 : A9, a9
2)数字不可以开头, 5c 不对
3)大小写不一样,长度无限制(65535)
4)不可以直接使用关键字和保留 字, 但是可以包含
5)不可以包含空格
命名规范:建议遵守
1)包名:全部小写;例 : atguigu.javase
2)类名、接口名:首字母大写,后面的其他单词首字母大写;例 MyClassNameSample 驼峰命名法
3)变量名:首字母小写,后面的其他单词首字母大写
4)常量名:全部大写,单词间用_隔开;例 : MY_FINAL_VARIABLE
多熟悉名字含义
变量:
内存中的一块被命名的并且要有特定数据类型约束的空间, 里面可以保存复合数据类型的一个数据 ,数据也可以随意在数据类型的范围内变化
数据类型的作用
决定空间大小
决定空间中能保存什么数据
决定空间中的数据可以做什么
变量使用注意事项
变量的概念:
内存中的一个存储区域
该区域有自己的名称(变量名)和类型(数据类型)
Java中每个变量必须先声明,后使用
该区域的数据可以在同一类型范围内不断变化
使用变量注意:
变量的作用域:一对{ }之间有效
初始化值:变量必须初始化才能使用
初始化:刚出生时赋的值
普通赋值:初始化后再被赋值
所以,变量最好这样使用 例:int n5 = 200;
定义变量的格式:
格式:数据类型 变量名;
变量是通过使用变量名来访问这块区域的
public class VariableAttention {
public static void main(String[] args) {
// 声明(declare) : 占地方, 宣告.
// 1) 必须要有数据类型和变量名;
// n3; 没有数据类型
// int; 没有变量名
int n1;
n1 = 200;
//System.out.println(n2);
// 2)n2必须应该先声明了, 再使用. 因为只有声明了变量才有内存空间.
int n2;
byte b1;
//b1 = 300; // 3) 空间中保存的数据只能在数据类型范围内!!!
// 4) 变量有其作用范围, 由其声明语句所隶属的一对{}决定
{
int a1; // a1只能在19行的{}内有效
a1 = 100;
//short a1;
}
//System.out.println(a1); // 超出了a1的使用范围
// 5) 同一个范围内, 变量不能重复声明
//double n1; // 重婚罪
short a1; // 因为它和面的a1不在同一个范围内
int n4;
// 6) 变量必须要初始化才能使用, 初始化 : 刚出生时赋的值
//System.out.println(n4);
n4 = 30; // 初始化 , 变量声明完后的第一次赋值
System.out.println(n4);
n4 = 40; // 普通赋值
// 变量最好这样使用
int n5 = 200;
}
}
分类
数值型
整数 :
byte 1字节 -128~127
short 2字节 -32768~32767
int 4字节 -20多亿~20多亿
long 8字节 -900多亿亿~900多亿亿
浮点型
字符型
字符型char 是存一个字符变量的类型,字符变量用' '概括表示,中间填入任意一个字符(也叫符号),例如'a' 'b' 'c' 之类。 多个字符可以拼接成一个字符串string,例如"hello world"。 以上两个都是字符,是符号,仅显示用,不能同数学一样参与计算,字符可以剪切或者粘贴到一个字符串中,可以判断是否一样的逻辑。
空间有限, 尽量用有限空间做成我们需要的数据
变量的声明:
格式:数据类型 变量名;
public class VariableTest {
public static void main(String[] args) {
// 变量 : 内存中的一块被命名有数据类型约空间, 可以保存一个数据, 此空间中的数据也可以变化.
// 变量声明 : 数据类型 变量名;
int n1; // 在内存中开辟4字节的空间, 并用n1符号 和这个空间 映射起来.
n1 = 20; // 把右面的20这个即时数据直接写入 n1符号 映射的内存空间中. 这个空间中就一直保存这个数据, 直到改变为止.
System.out.println(n1); // 打印n1符号映射的空间中的数据值. 是一个读数据 操作
int n2 = n1; // 暗含操作 : 1) 声明变量,在内存中开辟空间, 用n2符号映射此空间, 2) 根据右面n1符号 复制内存中的值20,
// 3)把这个20数据再写入n2符号映射的内存空间中.
//System.out.println(n2); // 20
// 赋值操作 : 把右面的值写入左面的变量符号 代表 的内存空间中.
// 赋值操作的最大特点 是反人类, 从右向左. 如果右面的值不确定, 绝对不可以向左走. 只有把右面全搞定 , 才能向左走.
n1 = n1 + n2;
// 先处理右面, 把n1符号引用的内存空间中的数据 复制出来 20 , 再把n2符号引用 的映射的空间中的数据 复制出来 20
// 20 + 20 => 40
// 把40这个确定的值真的写入 左面的n1符号所映射的内存空间中, 之前的数据直接被抹杀了.
System.out.println(n1);
System.out.println(n2);
System.out.println(n1);
}
}
n1 = 20 读法:n1被赋值20
变量按数据类型来分:
-
基本数据类型(primitive):内存空间中保存的就是数据本身(itself)
类型 | 分类 | 类型 | 占用存储空间 | 数据范围 | 比特 |
---|---|---|---|---|---|
数值型 | 整数 | byte | 1(byte) | -128~127 | 8bit |
short | 2 | -32768~32767 | 16bit | ||
int | 4 | -20多亿~20多亿 | 32bit | ||
long | 8 | -900多亿亿~900多亿亿 | 64bit | ||
字符型 | char | 2 | * | 16bit | |
浮点型 | float | 4 | -10的38次方~10的38次方 | 32bit | |
double | 8 | -10的308次方~10的308次方 | 64bit | ||
布尔型 | Boolean | 1 | true,false | 8bit |
数据类型的选取原则: 不要浪费空间, 不要空间不够
-
引用数据类型(reference):内存空间中保存的是别的数据的地址(address)
变量 :
内存中的一块空间, 可以保存一个数据
变量声明 :
数据类型 变量名;
变量使用注意事项 :
1) 必须要有数据类型和变量名
数值型之间的处理
// 结论 : 如果右面的量值的数据类型的范围小于或等于左面的变量的数据类型的范围, 是可以直接完成 // 结论 : 如果右面的量值的数据类型的范围大于左面的变量的数据类型的范围, 不可以直接完成, 必须要加上强制类型转换 // 兼容性从小到大 : byte < short < int < long < float < double // 浮点数字面量默认使用的8个字节double型来存储 // 整数字面量默认使用4个字节int型来存储
class DataTypeTest2 {
// 结论 : 只要是非long整数作运算, 至少要有一个变量参与, 结果一定是int型, 因为底层的指令只有iXXX.
// 如果有多种不同类型的变量的混合运算时, 结果的类型是参与的变量中的范围最大的那个类型
public static void main(String[] args) {
byte b1 = 10;
short s1 = 20;
//s1 = b1 + s1; // iadd
s1 = (short)(b1 + s1); // iadd
byte b2 = 5 + 8; // 这个虽然有运算, 但是没有变量参与, 所以可以直接完成
int i1 = 30;
b1 = (byte)(b1 + i1);
long l1 = 40L;
//i1 = l1 + i1;
i1 = (int)(l1 + i1); // long 强转为 int
i1 = (int)l1 + i1; //
float f1 = 3.2f;
double d1 = 5.7;
//l1 = f1 + l1; 右面的结果是float型
l1 = (long)(f1 + l1);
d1 = d1 + l1; // ?
}
}
public class DataTypeTest {
// 结论 : 如果右面的量值的数据类型的范围小于或等于左面的变量的数据类型的范围, 是可以直接完成
// 结论 : 如果右面的量值的数据类型的范围大于左面的变量的数据类型的范围, 不可以直接完成, 必须要加上强制类型转换
// 兼容性从小到大 : byte < short < int < long < float < double
// 浮点数字面量默认使用的8个字节double型来存储
// 整数字面量默认使用4个字节int型来存储
public static void main(String[] args) {
// b1和s1在底层其实就是int型, 如果在代码中特别指定了其他类型, 编译时需要注意一下
byte b1 = 10; // 10是int型, 因为10是常量, 永不改变. 这个值也正好可以被byte兼容, 这个操作编译器认为是可以的.
// 如果这个值不可以被byte兼容, 编译出错!!
short s1 = 20;
int i1 = 30;
long l1 = 40_0000_0000L; // 40亿, 后缀L的作用就是一个提醒, 提醒编译器这个整数字面量使用8字节的long型空间来保存
//b1 = s1; // 这个有错, 编译器认为这是变量, 不靠谱, 所以不可以直接赋值
byte b2 = b1;