引用数据类型
除了基本数据类型,都是引用类型,一般包含包含类、接口和数组,其实String类型也可以当作一种引用类型。引用类型占两块内存:一块为空值,定义一个引用类型;另一块为引用类型new出来的放堆里边进行动态内存分配,不用的时候就会被垃圾回收机制回收。
- 栈内存:存放堆内存中的真实对象地址
- 堆内存:存放new出来的动态对象,不用的时候就会被垃圾回收机制回收
关于引用类型如何使用在后边的blog会提到,关于Java的内存结构也会在后边提到,这里做简单记忆。
常量和变量
了解了数据类型和语法后,我们先来了解下Java里的常量和变量分别指什么。
变量
变量指的是值会改变的量,在Java中我们通过三个元素来描述变量:变量类型,变量名以及变量值。按照不同的角度,变量可以做如下的分类:
- 局部变量和成员变量:局部变量表示在方法体里面声明的变量,成员变量表示类体里面,方法体外边声明的变量,注意方法的参数属于局部变量,成员变量会默认初始化,而局部变量不会。成员变量并不能随意在各个方法中使用,如果想直接使用,成员变量与方法之前必须加static关键字,此时该成员变量或成员方法即相当于全局的概念,如果不加static,那么必须先new该类出一个实例,然后再调用变量和方法
- 按照方法的作用域划分:凡是在大括号里声明的变量,出了大括号就没人认识它了,在这个大括号里边的都认识它。
- 按照数据类型划分变量,不同的变量类型来划分。
变量还有一些特征和使用规范:
- Java 中的变量需要先声明后使用,变量使用时,可以声明变量的同时进行初始化,也可以先声明后赋值
- 命名规范:虽然语法中没有提示错误,但在实际开发中,变量名不建议使用中文,容易产生安全隐患,譬如后期跨平台操作时出现乱码等等
- 赋值规范:变量中每次只能赋一个值,但可以修改多次,main 方法中定义的变量必须先赋值,然后才能输出
以上就是变量的分类和使用规范了。
public class testvar { //int j; static int j; // 成员变量,可以作用于整个类 public void m() { // 虽然在main方法里也有i,但没关系,作用域都是本方法 int i = 0; System.out.println(i); } public static void main(String[] args) { int i=0 ; int t=i+5; //这里局部变量i必须先被赋初始值,否则不能编译。 int k=j+5; //成员变量可以不用赋初始值,系统会默认分配 System.out.println(k); //testvar tt=new testvar(); //非静态方法,需要先new出一个对象来,然后再调用 System.out.println(i); //System.out.println(tt.j); System.out.println(j); //只有成员变量定义为static,才可以直接打印 System.out.println("tianmaolin" + 123); // 这个属于常量的概念,直接可以打印相对应的常量值,不用定义声明赋值。 boolean b = false; if (b) { int c = 0; System.out.println("b is true"); } // System.out.println(c); //打印不出来,出了c的作用域了,根本就找不到c long longNum1 = 8888888888888L;
常量
所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变,常见常量类型有如下几种:
- 整形常量:int ,long
- 浮点型常量:float,double
- 字符常量(char):‘a’
- 字符串常量(string):“abcdefg”
- 逻辑常量(boolean):布尔类型,true ,false
常量还可以表示值不可以改变的变量,例如final关键字:final 常量名=值:final double PI=3.14。常量名一般使用大写字符。程序中使用常量可以提高代码的可维护性。例如,在项目开发时,我们需要指定用户的性别,此时可以定义一个常量 SEX,赋值为 “男”,在需要指定用户性别的地方直接调用此常量即可,避免了由于用户的不规范赋值导致程序出错的情况
运算符
按照运算符分类,Java支持如下的运算符类别:算数运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、字符串连接运算符。
- 算数运算符【7】:算术运算符包括通常的加(+)、减(-)、乘(*)、除(/)、取模(%),完成整数型和浮点型数据的算术运算;Java允许对浮点数进行取模操作。例如,3%2 的结果是 1, 15.2%5 的结果是 0.2。取模操作还可以用于负数,结果的符号与第一个操作数的符号相同,例如,5%-3 的结果是 2;算术运算符还有 自增(++)、自减(–)两种,分别称为加1和减1运算符。这两种运算符有前缀形式和后缀形式,含义有所不同。例如,i++ 和 ++i 的执行顺序是不一样的,i++ 在 i 使用之后再 +1,++i 在 i 使用之前先 +1。i-- 和 --i 的情况于此类似;2,-5%3 的结果是-2
- 位运算符【7】:位运算符用来对二进制位进行操作,包括按位取反(~)、按位与(&)、按位或(|)、异或(^)【相同为0相异为1】、右移(>>)、左移(<<)和无符号右移(>>>)。位运算符只能对整数型和字符型数据进行操作
- 关系运算符【7】:关系运算符用来比较两个值,包括大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)和不等于(!=)、instaceof(检查是否是类的对象)。关系运算符都是二元运算符,也就是每个运算符都带有两个操作数,运算的结果是一个逻辑值。Java允许“==”和“!=”两种运算符用于任何数据类型。例如,既可以判断两个数的值是否相等,也可以判断对象或数组的实例是否相等。判断实例时比较的是两个对象在内存中的引用地址是否相等
- 逻辑运算符【5】:逻辑运算符包括逻辑与(&)、逻辑与【短路版】(&&)、逻辑或(|)、逻辑或【短路版】(||)和逻辑非(!)。前两个是二元运算符,后一个是一元运算符。Java对逻辑与和逻辑或提供“短路”功能,也就是在进行运算时,先计算运算符左侧的表达式的值,如果使用该值能得到整个表达式的值,则跳过运算符右侧表达式的计算,否则计算运算符右侧表达式,并得到整个表达式的值
- 条件运算符【1】:也称为 “三元运算符”或“三目运算符”。语法形式( ? : ):布尔表达式 ? 表达式1 :表达式2。运算过程:如果布尔表达式的值为 true ,则返回 表达式1的值,否则返回 表达式2 的值。
- 赋值运算符【12】:赋值运算符的作用就是将常量、变量或表达式的值赋给某一个变量,,赋值符号 " = " 可以和算术运算符结合成复合赋值运算符,例如
= += -= *= /= %= &= |= ^= ~= <<= >>= >>>=
- 字符串连接运算符【1】:主要用来将和字符串连接的内容转为字符串**(+)**
以上这些运算符的优先级排序如下:
括号级别最高,逗号级别最低,单目 > 算术 > 位移 > 关系 > 逻辑 > 三目 > 赋值
语句
语句分为条件语句以及循环语句,接下来分别举例说明。
条件语句
条件语句有两种,if+else和switch:
public static void main(String[] args) { int i = 7; if (i < 20) { System.out.println("free"); } else if (i < 40) { System.out.println("normal:100yuan"); } else if (i < 60) { System.out.println("free"); } else { System.out.println("ok,you are right"); } }
switch语句如下所示:
public class choose { public static void main(String[] args) { int i = 7; switch (i) { //java中的switch只能探测int型的数据 case 3: System.out.println(33); break; //每个break必须要打,如果没有,就会发生case穿透问题,直接连同下一个case内容都打印出来 case 4: case 7: case 12: //多个case可以合并到一起,是或的关系 System.out.println(44); break; case 5: System.out.println(55); break; default: //default可以省略,但最好不要省略,破坏了程序的健壮性 System.out.println("error"); break; } }
循环语句
循环语句分为for循环语句、while语句以及do-while语句:
- for循环语句,一般有固定的循环次数
- while和do-while循环语句,一般没有固定的执行次数,其中while先判断再执行,do-while则先执行再判断
- 循环终止语句break和continue: break表示跳出,continue表示终止本次循环
以下为一个循环代码的示例:
public static void main(String[] args) { int result = 0; for (int i = 1; i <= 99; i += 2) { result += i; } System.out.println(result); int x = 0; while (x < 10) { System.out.println(x); x++; } //while....是先判断条件然后执行语句 x = 0; do { //do...while是先执行一次再判断条件 x++; System.out.println(x); } while (x < 10); //注意后边的分号!! int stop=4; for(int i=1;i<=10;i++){ if(i==stop) break; //注意if语句后边不要加分号!!!! System.out.println("i="+i); //终止整个语句块儿的循环,跳出循环语句 } int skip=3; for(int i=1;i<=10;i++){ if(i==skip) continue; //终止本次值的循环,直接跳到下一次 System.out.println("i="+i); } System.out.println(fabonacciloop(-3)); //用循环的方式解决斐波那契数列问题 }
分支+循环解决斐波那契数列问题:
public static long fabonacciloop(int index) { if (index<1) { System.out.println("erro"); return -1; } if (index == 1 || index == 2) { return 1; } else { long f1 = 1L; long f2 = 1L; long f = 0L; for (int i = 3; i <= index; i++) { f = f1 + f2; f1 = f2; f2 = f; //循环,变量互换赋值 } return f; } }
更多的测试代码如下:
public static void main(String[] args) { //每隔5个为一行打印出100内能被3整除的数 int num = 0; for (int i = 0; i < 100; i++) { //0~100之内能被3整除的数 if (i % 3 == 0) { System.out.println(i); num++; } if(num==5){ break; //如果计数达到5个可以被3整除,则终止计数 } }
public class testloop { //打印出100--200之间所有的质数 for (int i = 101; i < 200; i+=2) { boolean f=true; for (int j = 2; j < i; j++) { if (i%j==0) { f=false; //如果不是质数,设f为false,然后终止本次循环 break; //注意,这里只是把内层循环终止了 } } if(!f){ //如果不是质数,执行跳过,没跳过的都是质数,打印出来 continue; } System.out.println(i); } }
方法
方法表示一段特定功能的代码,包含:形参、实参、返回值、返回值类型、方法名。
public class testmethod { public static void main(String[] args) { //主车间,进行组装的地方 m(); m2(2); //这里传入的4, 相当于实参,实际传入的参数 m3('3', 4); m4(4, 6); //有返回值,但是并没有被打印出来 /*int i = m4(4, 6); System.out.println(i);*/ //把该返回值传给i,然后打印出该返回值 } public static void m() { //该分车间不返回任何值,只是顺序执行 //return; //直接return会报错,因为没有任何语句得到执行 System.out.println("ok"); System.out.println("hello"); } public static void m2(int i) { //形式参数i,必须传入一个值且必须为int类型的 if(i > 3) return; System.out.println(i); } public static void m3(int i, int j) { //该分车间可以有两个 System.out.println(i + j); } public static int m4(int i, int j) { //该分车间具有返回值 return i > j ? i : j; }