Java 基础知识
1 基本结构
Java程序基本结构包括包、类、main()主方法、标识符、关键字、语句和注释等。
Java语言中主方法的写法固定,除了可以修改形参String[]args为String args[],不可改变语句public static void main(String args[])的任何部分.
1.1 标识符与关键字
Java语言的标识符是字母、数字、下划线和美元符号组成,第一个字符不可以为数字;标识符不可以是Java的关键字和保留字;标识符区分大小写。
类名规范要首字母大写且后面每个单词首字母大写;变量名规范要首字母小写且后面每个单词首字母大写;方法名规范同变量名规范。
1.2 常量和变量
常量是固定不变的量,分类有字符串常量(双引号引起的部分)、整数常量(没有小数点的数)、浮点数常量(有小数点的数)、字符常量(单引号引起的单个字符,单引号中间必须有且仅有一个字符)、布尔常量(True、False两种取值)、空常量(nul,代表没有任何数据,不能够直接放在println方法中)。
1 package come_one; 2 3 public class demoone { 4 public static void main(String[] args) { 5 //字符串常量 字符数目可任意 6 System.out.println("Hello,World!!"); 7 System.out.println(""); 8 System.out.println("-^_^-"); 9 10 //整数常量 11 System.out.println(100); 12 System.out.println(-100); 13 14 //浮点数常量 15 System.out.println(3.14); 16 17 //字符常量 18 System.out.println('0'); 19 System.out.println(' '); 20 System.out.println('0'); 21 22 //布尔常量 23 System.out.println(true); 24 System.out.println(false); 25 26 //空常量不能直接打印输出,以下为错误写法 27 System.out.println(); 28 } 29 }
变量是程序运行期间内容可以发生改变的量。
创建一个变量并且使用的格式为:数据类型 变量名称;
赋值变量的格式为:变量名称 = 数据值;
一步到位的格式为:数据类型 变量名称 = 数据值;
1 package come_one; 2 3 public class demotwo { 4 public static void main(String args[]) { 5 //创建一个变量:数据类型 变量名称 6 int number1; 7 //变量中存入一个数据:变量名称=数据值 8 number1 = 100; 9 //打印变量 10 System.out.println(number1); 11 12 //一步走:数据类型 变量名称=数据值 13 int number2 = 20; 14 System.out.println(number2); 15 16 //改变变量值 17 number2 = 99; 18 System.out.println(number2); 19 } 20 }
1.3 数据类型
数据类型有基本数据类型和引用数据类型,基本数据类型有整数型(byte,short,int,long)、浮点型(float,double)、字符型(char)、布尔型(boolean),引用数据类型包含字符串、数组、类、接口、lambda。
注意1:字符串不是基本类型而是引用类型;
浮点类型是一个近似值,并非精确值;
数据范围与字节数不一定相关,如float数据范围比long更加广泛,但float是4字节,long是8字节。
浮点数中默认类型为double,如果需要使用float类型则需要加上后缀F。
如果是整数默认类型为int,如果需要之用long类型,则需要加上后缀L,如System.out.println(100L)中输出为长整数类型。
变量赋值数据不能够超出数据类型范围,否则会报错。
注意2:变量的创建中变量名称不重复;
对float和long类型而言,字母后缀F和L不能丢;
没有进行赋值的变量不可以直接使用;
使用byte或short类型的变量时右侧数据值不能够超过左侧数据类型的范围;
变量使用不能够超过作用域的范围(作用域是从变量定义的一行开始,直到直接所属的大括号结束为止);
可以通过一个语句来创建多个变量,可创建变量后各自赋值或者创建变量时赋值。
编译器的两个优化:对于byte/short/char类型的数据如果右侧赋值的数据没有超过范围,那么javac编译器将会自动隐含地补上一个(byte)(short)(char).如果没有超过左侧范围编译器补上则强制转换,如果右侧超过左侧范围,那么编译器会直接报错。在给变量赋值的时候,如果右侧的表达式全为常量没有任何变量,那么编译器javac会直接将若干个常量表达式计算得到结果(如 short res = 5+8;//等号右边全部是常量,编译完成后得到的class字节码文件中相当于short res = 13;这就不需要程序运行耗费cpu),但是表达式中有变量参与时则不能进行优化。(short a=5;short b=8;short res=a+b;这是错误写法,左侧需要int类型。)
1 package come_one; 2 //import java.util.*; 3 public class demotwo { 4 public static void main(String[] args) { 5 //创建一个变量:数据类型 变量名称 6 int number1; 7 //变量中存入一个数据:变量名称=数据值 8 number1 = 100; 9 //打印变量 10 System.out.println(number1); 11 12 //一步走:数据类型 变量名称=数据值 13 int number2 = 20; 14 System.out.println(number2); 15 16 //改变变量值 17 number2 = 99; 18 System.out.println(number2); 19 20 //浮点型与双精度类型 21 float number3 = 30.0F; 22 System.out.println(number3); 23 double number4 = 100.0; 24 System.out.println(number4); 25 26 //短型与长整型 27 short number5 = 30; 28 System.out.println(number5); 29 long number6 = 30000000000L; 30 System.out.println(number6); 31 32 //字节类型 33 byte number7 = 20; 34 System.out.println(number7); 35 36 //字符类型 37 char hanzi = '中'; 38 System.out.println(hanzi); 39 40 //布尔类型 41 boolean var1 = true; 42 System.out.println(var1); 43 boolean var2 = var1; 44 } 45 }
2 数据类型转换
数据类型不一样时会发生数据类型转换。数据类型转换有自动类型转换和强制类型转换两种。
自动类型转换的特点是代码不需要特殊处理能够自动完成,规则是数据范围从小到大。
强制类型转换的特点是代码需要进行特殊的格式处理不能够自动完成,格式是:范围小的类型(范围小的变量名) 范围小的变量名 = (范围小的类型)原本范围大的数据。
注意事项:强制类型不推荐使用,因为有可能发生精读损失、数据溢出。byte/short/char类型的数据可以发生数学运算,在运算时首先成为int类型再计算。布尔类型不能发生数据转换。
1 package come_one; 2 3 public class demo03 { 4 public static void main(String args[]) { 5 6 //数据类型转换服从数据范围从小到大 7 System.out.println(1024);//int类型 8 System.out.println(3.14);//double类型 9 10 //左边long类型,右边默认int类型,左右不一样 11 //将int常量放到long变量容器中存储 12 long num1 = 100; 13 System.out.println(num1);//100 14 15 //左侧是double类型,有测是float类型,左右不一样 16 //将float类型量放入double类型变量 17 double num2 = 1.5F; 18 System.out.println(num2); 19 20 //左边是float类型,右边是long类型 21 //数据类型 :long-》float 22 float num3 = 30L; 23 System.out.println(num3); 24 25 //等号左边为int,右边为long long变int不是从小到大 26 //不符合从小到大不能够自动类型转换 27 //范围小的类型 范围小的变量名 = (范围小的类型) 原本范围大的数据 28 int num4 = (int)100L; 29 System.out.println(num4); 30 31 //发生数据溢出 32 int num5 = (int)6000000000L;//1705032704 33 System.out.println(num5); 34 35 //发生精度损失 36 int num6 = (int)3.5; 37 System.out.println(num6);//不是四舍五入,小数位舍弃 38 39 char zifu1 = 'Z'; 40 System.out.println(zifu1 + 1); 41 //char类型进行数学运算时char会被翻译成为数字 42 43 byte num7 = 50; 44 byte num8 = 40; 45 //下语句报错,byte相加变成int+int 46 //byte res = num7 + num8; 47 int res = num7 + num8; 48 System.out.println(res); 49 50 short num9 = 10; 51 //int强制转换int,必须保证逻辑上真实大小本来没有超过short范围 52 short res2 = (short) (num9 + num8); 53 } 54 }
**128个ASCII码表关键记忆**
48对应'0',65对应'A',97对应'a'。除ASCII码外,码表还有Unicode万国码表。
3 运算符
运算符是进行特定操作的符号,表达式是运算符连接的式子。
运算符种类有算术运算符(+,-,*,/,%,++)、赋值运算符、比较运算符、逻辑运算符和三元运算符。
3.1 算术运算符
注意事项:一旦运算中有不同类型的数据,那么结果将会是数据类型范围大的那种。
加号'+’的三种用法:(1)对数值而言是加法;(2)对字母char类型而言在计算之前会提升成为int然后再计算(ASCII码表和Unicode表);(3)对字符串String(首字母大写)并不是关键字而言,加号代表字符串连接操作。任何数据类型和字符串进行连接的时候结果都会变成字符串。
只有变量才能使用自增自减运算符,常量不能使用自增自减。自增自减运算可以单独使用,不与其他任何操作混合,自己独立成为一个步骤;混合使用时可以和其他操作如赋值混合或与打印操作混合。单独使用时前++和后++结果无区别。混合使用时前++是变量马上+1拿着结果使用,后++是先使用变量后+1。
3.2 赋值运算符
赋值运算符包含基本赋值运算符'=’和复合赋值运算符(+=,-=,/=,*=,%=)。
只有变量才能使用赋值运算符,常量不能进行赋值。复合赋值运算符中隐含了强制类型转换。
3.3 比较运算符
比较运算符主要用于进行数值大小关系判断,其结果一定是Boolean值要么true要么false;
如果进行多次判断,则不能连着写如1<x<3这种数学形式不能直接写,而是:1 < x && x < 3。
3.4 逻辑运算符
逻辑运算符有与(并且,&&)、或(或者,||)、非(取反,!)这三种运算符。
与和或具有短路效果,根据左边已经可以判断得到最终结果,那么右边的代码将不再执行。
逻辑运算符只能用于Boolean型,与、或需要左右各自有一个Boolean值,但是取反只要有唯一的一个Boolean值,与或两种运算符如果有多个条件可以连续写。
3.5 三元运算符
一/二/三元运算符的区别需要数据的数目不同,一元运算如自增自减、取反,二元运算如加减乘除、赋值。
三元运算符的格式是:数据类型 变量名称 = 条件判断 ? 表达式A:表达式B;
首先判断条件是否成立,判断成立则将表达式A值赋值左侧变量,如果不成立则将表达式B值赋值左侧变量,二者选其一。
注意:需要同时保证表达式A和表达式B都符合左侧数据类型的要求。
三元运算符的结果必须被使用,不能够单独成语句。
1 package come_one; 2 3 public class demo04 { 4 public static void main(String args[]) { 5 //算术运算符 6 int a = 30; 7 int b = 20; 8 System.out.println(a + b); 9 System.out.println(a - b); 10 System.out.println(a * b); 11 System.out.println(a / b); 12 System.out.println(a % b); 13 System.out.println(a++); 14 System.out.println(a); 15 //int + double -> double + double = double 16 System.out.println(a + 2.5); 17 //混合使用 18 int result = --a; 19 System.out.println(result); 20 21 //字符串类型变量 22 String str1 = "Hello"; 23 String str2 = "World"; 24 System.out.println(str1 + str2); 25 //优先级问题 String > int 26 //String + int + int = String + int = String 27 System.out.println("Java"+1+5); 28 System.out.println("Java"+(1+5)); 29 30 //赋值运算符 31 int num1 = 20; 32 num1 -= 2; 33 System.out.println(num1); 34 num1 += 2; 35 System.out.println(num1); 36 num1 /= 2; 37 System.out.println(num1); 38 num1 *= 2; 39 System.out.println(num1); 40 num1 %= 8; 41 System.out.println(num1); 42 43 //比较运算符 44 //《 》 《= 》= == != 45 System.out.println(10 > 5); 46 System.out.println(10 < 5); 47 System.out.println(10 != 5); 48 System.out.println(10 <= 5); 49 System.out.println(100 == 100); 50 51 //逻辑运算符 52 System.out.println(true && false); 53 System.out.println(3 < 4 && 100 != 100); 54 System.out.println(true || false); 55 System.out.println(3 < 4 || 100 != 100); 56 System.out.println(!true); 57 58 //三元运算符 59 int max; 60 a = 20; 61 b = 15; 62 max = (a > b) ? a : b; 63 System.out.println("最大值:"+max); 64 } 65 }
4 方法入门
方法是将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个单独的功能,当需要这个功能的时候就可以去调用,以此实现代码的复用性、代码的冗余性问题。方法是若干语句的功能集合,包含参数与返回值。参数是进入方法的数据,返回值是方法中出来的数据。
方法定义的格式:public static void 方法名称(){ 方法体 }。方法名称的命名规则与变量命名规则相同采用小驼峰式,方法体是大括号中可以包含任意条语句。定义方法的完整格式是:修饰符(public static) 返回值类型(方法最终产生的数据结构的类型) 方法名称(参数类型 参数名称,...){方法体 + return 返回值;}
return作用:第一是停止当前方法,第二是将后面的返回值还给调用处。返回值是方法执行后最终产生的数据结果。
调用方法的格式:方法名称();
方法调用过程是找到方法-参数传递-执行方法体-带着返回值回到方法的调用处
方法调用有单独调用、打印调用、赋值调用三种。void返回值类型的方法只能够单独调用不能够赋值调用和打印调用。
方法参数情况可以分为有参数和无参数两种,有参数是指小括号中有内容;无参数是小括号中留空,一个方法不需要任何数据条件自己就能独立完成任务。
方法返回值可以分为有返回值和无返回值,根据需求决定。
注意事项:
方法定义的先后顺序无所谓,方法的定义不能产生嵌套包含关系,方法定义后不会执行如果要执行则要进行方法的调用。
return后面的返回值必须和方法名称前面的返回值类型保持对应。方法定义在类当中,不能在方法中定义方法(不能嵌套)。
对于return没有返回值的方法,不能写return后面的返回值,只能return自己(即“return;”)。
方法中最后一行的return可以省略不写。一个方法中可以有多个return,但是必须保证同时只有一个return会执行到,两个return不能连写。
public class demo05 { public static void main(String args[]) { //将菜的过程用代码体现出来,但是这么多代码无法分清楚执行的对象是谁 //可以将以下步骤分成四个主要对象,每个执行内容可以定义一个方法 //农民伯伯 System.out.println("播种"); System.out.println("浇水"); System.out.println("施肥"); System.out.println("除虫"); System.out.println("收割"); System.out.println("卖给小商贩"); //小商贩 System.out.println("运输到农贸市场"); System.out.println("抬高价格"); System.out.println("吆喝"); System.out.println("卖给厨子"); //厨子 System.out.println("洗菜"); System.out.println("切菜"); System.out.println("炒菜"); System.out.println("装盘"); //我 System.out.println("吃"); }
package come_one; public class demo05 { public static void main(String args[]) { //将菜的过程用代码体现出来,但是这么多代码无法分清楚执行的对象是谁 //可以将以下步骤分成四个主要对象,每个执行内容可以定义一个方法 //下面采用方法的途径来实现调用 farmer(); saler(); cook(); me(); } //农民伯伯 public static void farmer() { System.out.println("播种"); System.out.println("浇水"); System.out.println("施肥"); System.out.println("除虫"); System.out.println("收割"); System.out.println("卖给小商贩"); } //小商贩 public static void saler() { System.out.println("运输到农贸市场"); System.out.println("抬高价格"); System.out.println("吆喝"); System.out.println("卖给厨子"); } //厨子 public static void cook() { System.out.println("洗菜"); System.out.println("切菜"); System.out.println("炒菜"); System.out.println("装盘"); } //我 public static void me() { System.out.println("吃"); } }
package come_two; public class demo01 { public static void main(String args[]) { //打印调用 System.out.println(addTwonum(10,20)); System.out.println("---------------"); //单独调用 addTwonum(10,20); System.out.println("---------------"); //赋值调用 int sum = addTwonum(10,20); System.out.println("变量的值:"+sum); } public static int addTwonum(int a,int b) { System.out.println("方法执行!"); int sum; sum = a + b; return sum; } }
方法重载(Overload):
方法重载是方法名称相同但是参数列表不同,好处是只需要记住一个方法名称就可以实现类似的功能。
方法重载与下列因素相关:参数个数不同,参数类型不同(可以强制转换或自动转换),参数类型顺序不同。
方法重载与下列因素无关:参数名称,方法的返回值类型
package come_two; public class demo02 { public static void main(String args[]) { System.out.println(sum(10, 10, 10, 10)); System.out.println(sum(10, 10, 10)); System.out.println(sum(10, 10)); } //方法重载:可实现多个参数的使用,名称相同但是参数列表不同 public static int sum(int a,int b) { return a + b; } public static int sum(int a,int b,int c) { return a + b + c; } public static int sum(int a,int b,int c,int d) { return a + b + c + d; } }
package come_two; //方法重载练习1 //比较两个数据是否相等 //参数类型为2个byte,2个short,2个int,2个long,并在main中测试 public class demo02 { public static void main(String arg[]) { byte a = 10; byte b = 20; System.out.println(isSame(a, b)); System.out.println(isSame((short)10, (short)20)); System.out.println(isSame(15,15)); System.out.println(isSame(100L, 100L)); } public static boolean isSame(byte a, byte b) { boolean same; if(a == b) { same = true; }else { same = false; } return same; } public static boolean isSame(short a, short b) { boolean same = a == b ? true:false; return same; } public static boolean isSame(long a, long b) { return a == b; } public static boolean isSame(int a, int b) { if(a == b) { return true; }else { return false; } } }
5 流程与语法结构
流程有三种:顺序、循环、选择结构。
顺序结构:开始->步骤A->步骤B->步骤C->结束,按箭头顺序操作执行。
判断语句(选择结构):单if语句,if-else语句,复合if..else if... else语句,三元运算符和if-else语句比较。
选择语句(switch):每种情况用case表示,不满足则用default。switch后面小括号中仅能是下列数据类型(基本数据类型:byte/short/char/int;引用数据类型:String字符串、enum枚举)。switch语句前后顺序可以颠倒,而且break语句可以省略,匹配哪一个case就从哪一个位置向下执行,直到遇到break或者整体结束为止。
package come_one; //单if语句 public class demo06 { public static void main(String args[]) { System.out.println("今天天气不错,正在遛马路,突然发现一个快乐的地方:网吧"); //int age = 16; //条件满足执行语句体,不满足则跳过 int age = 18; if(age >= 18) { System.out.println("进入网吧,开始high!"); System.out.println("遇到了一群猪队友,开始骂街"); System.out.println("感觉不舒服,结账走人"); } System.out.println("回家吃饭"); } }
package come_one; //if-else语句 public class demo06 { public static void main(String args[]) { int num = 666; if(num % 2 == 0) { System.out.println(num+"为偶数"); }else { System.out.println(num+"为奇数"); } } }
package come_one; //if-else if - else复合语句 public class demo06 { public static void main(String args[]) { int x = 2; int y; if(x >= 3) { y = 2 * x + 1; }else if(-1 < x && x < 3) { y = 2 * x; }else { y = 2 * x - 1; } System.out.println("结果是:"+ y); } }
package come_one; //使用三元运算符和标准的if-else语句分别实现两个数字的最大值 public class demo06 { public static void main(String args[]) { int a = 20; int b = 30; //三元运算符 int max = a > b ? a : b; int max1; if(a > b) { max1 = a; }else { max1 = b; } System.out.println(max); System.out.println(max1); } }
package come_one; //switch语句 public class demo06 { public static void main(String args[]) { int num = 5; switch(num) { case 1 : System.out.println("星期一"); break; case 2 : System.out.println("星期二"); break; case 3 : System.out.println("星期三"); break; case 4 : System.out.println("星期四"); break; case 5 : System.out.println("星期五"); break; case 6 : System.out.println("星期六"); break; case 7 : System.out.println("星期日"); break; default: System.out.println("数据错误"); break;//最后一个break可以省略,但建议保留 } } }
循环结构是满足循环条件情况下反复执行某一段代码即循环体,在合适的时候将循环条件修改为False而结束循环。循环结构的基本组成部分可以分为初始化语句(在循环开始最初执行,而且只做唯一一次)、条件判断、循环体(重复做的若干行语句,事件内容)、步进语句(每次循环之后进行的扫尾工作,每次循环结束后都要执行一次)。
循环语句有for循环语句,结构为for(初始化表达式;布尔表达式;步进表达式)+ 循环体。
while循环有一个标准格式还有一个扩展格式。标准格式是while(条件判断)+循环体,扩展格式是初始化语句+while(条件判断)+循环体(后跟步进语句)。
do-while语句的格式是do+循环体+while(条件判断);程序遇到do则无条件执行循环体内容,执行完后判断条件是否成立。扩展格式为初始化语句+do+循环体(后跟步进语句)+while(条件判断);
package come_one; public class demo07 { public static void main(String args[]) { //for语句 for(int i = 1;i <= 10;i++) { System.out.println(i+"我错了!请原谅我"); } //while语句扩展格式 int i = 1; while(i<=10) { System.out.println(i+"-我错了!请原谅我"); i++; } //do-while循环 int j = 1; do { System.out.println(j+"--我错了!请原谅我"); j++; }while(j <= 10); } }
三种循环的区别:
1.如果条件判断不满足,那么for循环和while循环将会执行0次,但是do-while循环会执行至少一次。
2.for循环的变量在小括号中定义,是局部变量,只有在循环内部才可以使用。while循环和do-while循环的初始化语句在外面,出循环后可以继续使用。
***补充:
break关键字可用于switch中,一旦执行整个switch语句立刻结束。还可以应用于循环语句中,一旦执行整个循环语句立刻结束,打断循环。次数确定的场景可以用for循环,否则可以用while循环。continue关键字一旦执行立刻跳过当前次循环剩余内容马上开始下一次循环。
6 数组
数组是一种容器,可以同时存放多个数据值。
数组的特点:数组是一种引用的数据类型;数组当中的多个数据,类型必须统一;数组的长度在程序运行期间不可改变。
数组的初始化是在内存中创建一个数组并且向其中赋予一些默认值。初始化方式可以是动态初始化(指定长度)和静态初始化(指定内容)、省略格式。虽然静态初始化没有直接告诉长度,但是根据大括号里面元素具体内容也可以自动计算出长度。静态初始化和动态初始化可以拆分为两个步骤,具体写代码表达。静态初始化一旦使用省略格式则不能够拆分为两个步骤。动态初始化数组时元素自动拥有一个默认值,整数类型默认0,浮点类型默认0.0,字符类型默认\u0000,布尔类型默认false,引用类型默认null。静态初始化其实也有默认值过程,只不过系统自动马上将默认值替换成为了大括号中具体数值。
直接打印数组名称得到的是数组对应的内存哈希地址。
两个数组的引用可以用arrayA = arrayB实现,即将arrayB的地址传送给arrayA,引用后A或B修改会影响两者。
数组索引编号从0开始到数组长度-1为止,访问数组元素的时候索引编号不存在将会发生数组索引越界异常ARRAYINDEXOUTOFBOUNDSEXCEPTION,原因是索引编号错误,通过修改正确索引编号可解决问题。
所有的引用类型变量都可以赋值为null值,但是代表其中什么都没有。数组必须进行new初始化才能使用其中的元素,如果只是赋值一个null则没有进行new创建,那么将会发生空指针异常(NULLPOINTEREXCEPTION),原因是忘了new,补上new则可解决。int []arrayA = null; arrayA = new int[3];
数组的长度在程序运行期间不可改变。数组可以作为方法的参数和方法返回值实现传输或返回地址。如果希望方法中产生多个结果数据进行返回时可以使用一个数组作为返回值类型。
JAVA的内存需要分五个部分:(红色部分为重点)
1.栈(STACK):需要存放方法中局部变量,方法的运行一定要在栈当中。局部变量是方法的参数,具有作用域(一旦超出作用域like从栈内存消失)
2.堆(HEAP):凡是new出来的东西都在堆当中,堆内存里面的东西都有一个地址值(16进制),堆内存里面的数据都有默认值(整数默认0,浮点默认0.0,字符默认\u0000,布尔默认false,引用默认null)
3.方法区(METHOD AREA):存储class相关信息,只是包含方法的信息,真正方法的运行在栈。
4.本地方法栈(NATIVE METHOD STACK):与OS相关。
5.寄存器(PC REGISTER):与CPU相关。
package come_two; public class demo03 { public static void main(String arg[]) { //数组动态初始化的数据格式,直接指定数据元素个数 //数据类型[] 数组名称 = new 数据类型[数组长度] //左侧数据类型也就是保存的数据全部是统一的类型 //左侧的中括号代表是一个数组,数组名称表示一个名字 //右侧的new表示创建数组的动作,数据类型必须和左边数据类型一致 //数组长度表示数组中可以保存多少个数据,是一个int数字 int [] arrayA = new int[300];//创建数组 double [] arrayB = new double[10]; String[] arrayC = new String[100]; int [] arrayAA; arrayAA = new int[] {100,200,300}; //静态初始化基本格式:数据类型[] 数据名称 = new 数据类型[]{元素1,元素2,...} int [] arrayD = new int[] {5,15,25}; String [] arrayE = new String[] {"Hello","World"}; //省略格式:数据类型[] 数组名称={元素1,元素2,...}; int []arrayZ = {10,20,30}; } }
package come_two; public class demo04 { public static void main(String args[]) { int [] array1 = {10,20,30}; System.out.println(array1);//[I@6a5fc7f7 内存地址 //访问数组元素的格式:数组名称[索引值] //索引值从0开始,一直到数组长度-1为止,代表数组当中元素的编号。 System.out.println(array1[0]); System.out.println(array1[1]); //动态初始化与赋值 int [] array2 = new int[3]; System.out.println(array2); System.out.println(array2[0]); System.out.println(array2[1]); array2[0] = 100;//100赋值给0号元素 System.out.println(array2[0]); } }
package come_two; //java内存部分分析 public class demo05 { public static void main(String args[]) { int []array = new int[3];//动态初始化 System.out.println(array);//地址值 System.out.println(array[0]);//0 System.out.println(array[1]);//0 System.out.println(array[2]);//0 array[0] = 100; array[1] = 200; array[2] = 300; System.out.println(array);//地址值不变 System.out.println(array[0]);//100 System.out.println(array[1]);//200 System.out.println(array[2]);//300 /* 栈: main(String args[])信息在栈中运行,开辟一段栈中新内存空间 局部变量 int []array 数组名称即变量在栈中,根据地址可以找到堆中数组 System.out.println(array); 保存地址 array[0] 找到地址0x???? 重新赋值时修改堆内数组空间元素值 堆: new int[3]在堆中开辟三个空间默认值为0,空间起始有地址0x????, 方法区: main方法头放在方法区 public static void main(String args[]) */ } }
package come_two; /* 1.如何获取数组的长度与格式:数组名称.length 2.遍历数组:将数组中每一个元素逐一打印输出. 3.求最大值 4.数组元素反转:不能够使用新数组,使用原数组 */ public class demo06 { public static void main(String args[]) { int [] array = {10,20,30,40,50,60,70,80,90,100}; int len = array.length; System.out.println("数组array的长度是:"+len); //遍历输出,for循环或者原始顺序输出 for(int i = 0; i < array.length;i++) { System.out.println(array[i]); } printArray(array);//调用数组方法 //最值判断 int max = array[0]; for(int i = 1; i < array.length; i++) { if(array[i] > max) { max = array[i]; } } System.out.println("最大值:"+max); //数组元素反转:是对称位置的元素交换 //对称位置需要两个索引:min,max //min==max或min》max时停止交换 即 min《max时应该交换 int []arrayA = new int[] {10,15,6,100,89}; for(int i = 0; i < arrayA.length;i++) { System.out.println(arrayA[i]); } for(int min_1 = 0,max_1 = arrayA.length - 1; min_1 < max_1; min_1++,max_1--) { if(min_1 < max_1) { int temp = arrayA[min_1]; arrayA[min_1] = arrayA[max_1]; arrayA[max_1] = temp; } } for(int i = 0; i < arrayA.length;i++) { System.out.println(arrayA[i]); } System.out.println("============="); //老数组,长度永远是3不能改变 int [] array1 = new int[3];//创建一个三个格子的变量空间 System.out.println("数组array1的长度是:"+array1.length); //新数组,这里数组指的是堆中内容 array1 = new int[5];//又创建新的5个格子的变量空间 System.out.println("数组array1的长度是:"+array1.length); } public static void printArray(int array[]) { for(int i = 0; i < array.length;i++) { System.out.println(array[i]); } } }
package come_two; //数组作为方法的返回值返回的其实也是地址值 //数组作为方法的参数传递进去的也是数组的地址值 public class demo07 { public static void main(String args[]) { int []result = caculate(10, 20, 30); System.out.println("main方法内部数组是"); System.out.println(result);//地址值 System.out.println("总和为:"+result[0]); System.out.println("平均值为:"+result[1]); } public static int[] caculate(int a,int b,int c) { int sum = a + b + c; int avg = sum / 3; /* int []array = new int[2]; array[0] = sum; array[1] = avg; */ int array[] = {sum,avg}; System.out.println("caculate方法内部数组是"); System.out.println(array);//地址值 return array; } }
7 面向对象
7.1 过程和对象
面向过程是当需要实现一个功能时每一个具体的步骤都要亲力亲为,详细处理每一个细节,强调步骤。
面向对象是当需要实现一个功能时不关心具体的步骤,而是找一个已经具有该功能的人来做事,强调对象。面向对象的特点是找一种复合思考习惯的思想,将复杂的事情简单化并且将我们从执行者变成指挥者。面向对象中包含了封装、继承和多态三大基本特征。
封装是面向对象的核心。将对象的属性和行为封装起来,将对象的属性和行为封装起来的载体是类,类通常对客户隐藏实现细节。封装是将一些细节信息隐藏起来,对于外界不可见。封装在JAVA中的体现有(方法是封装,关键字private是封装)。
private(提高了代码的安全性)修饰时本类中仍然可以访问,但是超出本类之外不可直接访问,但可以间接(具体步骤是get和set写方法设置,set设置无返回值有参数,get设置有返回值无参数)。
继承是类与类间存在关联,A类与B类有关联但不完全相同时,B类可以保留和继承A类的共同特征,缩短软件开发时间,复用已定义好的类。继承主要体现为父类和子类间的联系。
父类对象应用于子类对象的特征是多态,多态的实现依赖于抽象类和接口。多态中父类通常定义为抽象类,在抽象类中给出一个方法的标准而不给出实现的具体流程。而在多态的机制中,比抽象类更为方便的方式是将抽象类定义为接口,由抽象方法组成的集合即为接口。
方法局部变量和类的成员变量重名的时候,根据就近原则优先使用局部变量。如果需要访问本类中的成员变量,需要使用格式this.成员变量。(通过谁调用的方法,谁就是this)
package come_three; import java.util.Arrays; import java.util.Iterator; public class demo01 { public static void main(String args[]) { int []array = {10,20,30,40,50}; //面向过程,每个步骤亲力亲为 System.out.println("["); for(int i = 0; i < array.length; i++) { if(i == array.length - 1) { System.out.println(array[i] + "]"); }else { System.out.println(array[i]+","); } } //面向对象:找一个JDK提供好的array类 //其中tostring方法直接把数组编程想要的格式的字符串 System.out.println("==========="); System.out.println(Arrays.toString(array)); } }
//文件1package come_three; /* 定义年龄时无法阻止不合理的数值设置进来,通过private保护成员变量进行修饰 一旦使用private修饰那么本类中仍然可以随意访问,但是超出了本类范围之外的不能够直接访问 */ public class Person { String name; private int age; public void show() { System.out.println("我叫:"+name+",年龄:"+age); } //这个成员方法用于向成员变量age设置值 public void setAge(int num) { if (num < 100 && num >= 0) { age = num; }else { System.out.println("数据不合理"); } } //这个方法用于获取age public int getAge() { return age; } } //文件二 package come_three; public class demo07 { public static void main(String args[]) { Person person = new Person(); person.show(); person.name = "丁香医生"; person.setAge(20); person.show(); } }
package come_three; /* public class demo09 { String name; //参数who是对方的名字 //成员变量name是自己的名字 public void sayHello(String who) { System.out.println(who + ",你好。我是" + name); } } */ /* 方法局部变量和类的成员变量重名的时候,根据就近原则优先使用局部变量。如果需要访问本类中的成员变量,需要使用格式this.成员变量 通过谁调用的方法,谁就是this */ public class demo09 { String name; //参数who是对方的名字 //成员变量name是自己的名字 public void sayHello(String name) { System.out.println(name + ",你好。我是" + this.name); } } package come_three; public class demo10 { public static void main(String args[]) { demo09 persons = new demo09(); persons.name = "王健林"; persons.sayHello("王思聪"); } }
7.2 类和对象
类是一种相关属性和行为的集合,是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。属性是事物的状态信息,行为是事物能够做什么。对象是一类事物的具体体现,对象是类的一个实例,必然具备该类事物的属性和行为。
比如:手上有个手机,手机的长宽高的特征是属性,手机可以打电话发短信的能力是行为。
关系:类是对一类事物的描述,抽象的。对象是一类事物的具体实例,是具体的。类是对象的模板,对象是类的实体。
注意事项:成员方法直接定义在类当中,在方法外边;成员方法不要写static关键字。
通常一个类并不能直接使用,需要根据类创建一个对象才能使用。
需要以下步骤:
1.导包:也就是指出需要使用的类在什么位置。
import 包名称.类名称
对于和当前类属于同一个包的情况,可以省略包语句不写。
2.创建,格式:
类名称 对象名 = new 类名称();
3.使用,分为两种情况:
使用成员变量,对象名.成员变量名
使用成员方法,对象名.成员方法名(参数)
成员变量没有进行赋值时会有默认值,规则和数组相同。
成员变量和局部变量的区别:+ 方法的参数就是局部变量,参数在方法调用时必然被赋值。
1.定义位置不同:局部变量定义在方法内部;成员变量定义在方法外部,直接写在类中。
2.作用范围不一样:局部变量只有在方法中使用,出了方法不可以使用;整个类全部可以使用。
3.默认值不一样:局部变量没有默认值,如果要想使用必须手动赋值;成员变量不赋值会有默认值,规则和数组一样。
4.内存位置不一样:局部变量位于栈内存,成员变量位于堆内存
5.生命周期不一样:局部变量随着方法进栈产生,随着方法出栈消失;成员变量随着对象创建而产生,随着对象被垃圾回收而消失。
package come_three; /* public class Classname{ //成员变量 //成员方法 } */ /* 定义一个类,用于模拟学生事务,其中有两个组成部分 属性(是什么) 姓名 年龄 行为(能做什么) 吃饭 睡觉 学习 对应到JAVA类中: 成员变量(属性) String name; int age; 成员方法(行为) public void eat(); public void sleep(); public void study(); */ public class demo02 { //成员变量 String name;//姓名 int age;//年龄 //成员方法 public void eat() { System.out.println("吃饭"); } public void sleep() { System.out.println("睡觉"); } public void study() { System.out.println("学习"); } }
package come_three; public class demo03 { public static void main(String args[]) { //导包 //使用的类在同一个包下可以省略导包语句 //创建 demo02 stu = new demo02(); //使用其中成员变量 System.out.println(stu.age); System.out.println(stu.name); stu.age = 36; stu.name = "赵丽颖"; System.out.println(stu.age); System.out.println(stu.name); stu.eat(); } }
package come_three; public class demo04 { public static void main(String args[]) { //根据Phone类创建一个phone的对象 Phone phone = new Phone(); System.out.println(phone.brand); System.out.println(phone.color); System.out.println(phone.price); phone.brand = "iPhone SE"; phone.price = 8888; phone.color = "Blue"; System.out.println(phone.brand); System.out.println(phone.color); System.out.println(phone.price); phone.call("乔布斯"); phone.sendMessage(); //引用 Phone phone1 = phone; System.out.println(phone1.brand); System.out.println(phone1.color); System.out.println(phone1.price); phone1.brand = "iPhone SE"; phone1.price = 8888; phone1.color = "Blue"; System.out.println(phone1.brand); System.out.println(phone1.color); System.out.println(phone1.price); phone.call("乔布斯"); phone.sendMessage(); } }
package come_three; public class demo05 { public static void main(String args[]) { //使用对象类型作为方法的参数 //Phone one = new Phone(); //one.brand = "华为"; //one.color = "Blue"; //one.price = 8338; //method(one);//传递进去的参数是地址值 //使用对象类型作为方法的返回值 Phone two = gethPhone(); System.out.println(two.brand); System.out.println(two.color); System.out.println(two.price); } //使用对象类型作为方法的参数 public static void method(Phone param) { System.out.println(param.brand); System.out.println(param.color); System.out.println(param.price); } //使用对象类型作为方法的返回值 public static Phone gethPhone() { Phone one = new Phone(); one.brand = "苹果"; one.price = 8338; one.color = "BLUE"; return one; } }
package come_three; /* boolean类型当中的boolean值 get方法一定要写成isXXX的形式 */ public class Student { private String name; private int age; private boolean male; public void setMale(boolean b) { male = b; } public boolean isMale() { return male; } public void setName(String str) { name = str; } public String getName() { return name; } public void setAge(int num) { age = num; } public int getAge() { return age; } } package come_three; public class demo08 { public static void main(String args[]) { Student stu = new Student(); stu.setName("芦荟"); stu.setAge(20); stu.setMale(true); System.out.println("姓名:"+stu.getName()); System.out.println("年龄:"+stu.getAge()); System.out.println("是不是爷们儿:"+stu.isMale()); } }
7.3 构造方法
加入构造方法后,类可以由四部分组成:成员变量,无参构造,有参构造,setter和getter。
1. 构造方法的名称和所在的类名称完全一样,大小也一样。
2. 构造方法不需要返回值类型,void都不写。
3. 构造方法的调用是通过new关键字加上构造方法名称,而不是通过“.”
4. 构造方法不能return一个具体的返回值。
5. 如果没有编写任何构造方法,编译期将会默认赠送一个构造方法,没有参数,方法体什么事情都不做。
6.一旦编写至少一个构造方法,那么编译器将不再赠送。
7.构造方法重载:方法名称相同,参数列表不同
package come_three; /* 构造方法是专门用来创建对象的方法,当通过关键字new来创建对象时其实就是在调用构造方法。 格式: public 类名称(参数类型 参数名称){ 方法体 } */ public class demo11 { //成员变量 private int age; private String name; //无参构造 public demo11() { System.out.println("无参构造方法执行了!"); } //重载:有参构造 public demo11(String name,int age) { System.out.println("有参构造方法执行了!!"); this.name = name; this.age = age; } //GETTER SETTER public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public String getName() { return name; } } package come_three; public class demo12 { public static void main(String args[]) { demo11 demo1 = new demo11(); //无参 demo11 demo2 = new demo11("赵丽颖",20); //全参 System.out.println("姓名:" + demo2.getName() + ",年龄:" + demo2.getAge()); //改变对象中成员变量数据内容仍然需要使用setter方法 demo2.setAge(22); System.out.println("姓名:" + demo2.getName() + ",年龄:" + demo2.getAge()); } }
package come_four; /* 一个标准的类通常满足下面四个组成部分 1.所有的成员变量都要使用private关键字修饰 2.为每一个成员变量编写一对getter/setter 3.编写一个无参构造方法 4.编写一个有参构造方法 标准的类成为 JAVA BEAN */ public class Student { private String name; private int age; //无参构造 public Student() { } //有参构造 public Student(String name,int age) { this.name = name; this.age = age; } //GETTER SETTER public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public String getName() { return name; } } package come_four; public class demo01 { public static void main(String args[]) { Student stu1 = new Student(); stu1.setName("迪丽热巴"); stu1.setAge(22); System.out.println("姓名:" + stu1.getName() + ",年龄:" + stu1.getAge()); System.out.println("==========="); Student stu2 = new Student(); stu2.setName("古力娜扎"); stu2.setAge(32); System.out.println("姓名:" + stu2.getName() + ",年龄:" + stu2.getAge()); System.out.println("==========="); } }
7.4 API和Scanner
API(Application Programming Interface)是应用程序编程接口,是JDK提供给使用的类的说明文档。
API使用步骤:打开帮助文档;点击显示找到索引,回车;在输入框输入名称后回车;看包(java.lang的类不需要导入包,其他需要);看类的解释和说明;学习构造方法;使用成员方法。
Scanner是用户能够通过键盘输入到程序中,使用步骤是导包、创建、调用。
package come_four; /* scanner是一个类,可以实现键盘输入数据到程序中 引用类型的一般使用步骤: 1.导入包 import 包路径.类名称 如果需要使用的目标类和当前类位于同一个包可以省略导包语句 2.创建 类名称 对象名 = new 类名称(); 3.使用 对象名.成员方法名(); */ import java.util.Scanner; //导包 public class demo02 { public static void main(String args[]) { //创建 //System.in表示从键盘进行输入 Scanner sc = new Scanner(System.in); //第一个案例:两个数字相加 //System.out.println("请输入第一个数字"); //int num1 = sc.nextInt(); //System.out.println("请输入第二个数字"); //int num2 = sc.nextInt(); //int result = num1 + num2; //System.out.println("输入的数字和是:" + result); //第二个案例:三个数最大? System.out.println("请输入第1个数字"); int num1 = sc.nextInt(); System.out.println("请输入第2个数字"); int num2 = sc.nextInt(); System.out.println("请输入第3个数字"); int num3 = sc.nextInt(); int temp = num1 > num2 ? num1 : num2; int max = temp > num3 ? temp : num3; System.out.println("输入的数字最大值是:" + max); //获取键盘输入的字符串 //String str = sc.next(); //System.out.println("输入的String字符串是:" + str); } }
7.5 匿名对象
匿名对象是只有右边的对象,没有左边的名字和赋值运算符。格式:new 类名称();匿名对象只能使用唯一的一次,下次再用不得不再创建一个新对象。如果确定有一个对象只需要使用唯一的一次,就可以用匿名对象。匿名对象也可以作为参数和返回值。
package come_four; import java.util.Scanner; /* 创建对象标准格式 类名称 对象名 = new 类名称(); */ public class demo03 { public static void main(String args[]) { //匿名对象的创建 // new Person().name = "吴协康"; // new Person().showName(); // 我叫,null //普通使用方式 // Scanner sc = new Scanner(System.in); // int num = sc.nextInt(); //匿名对象方式:使用一次 // int nums = new Scanner(System.in).nextInt(); // System.out.println("输入的是:" + nums); //使用一般写法传入参数 // Scanner sc = new Scanner(System.in); // methodParam(sc); //使用匿名对象传入参数 // methodParam(new Scanner(System.in)); Scanner sc = methoReturn(); int num = sc.nextInt(); System.out.println("输入的是:" + num); // Person one = new Person(); // one.name = "杨毅"; // one.showName(); } public static void methodParam(Scanner sc) { int num = sc.nextInt(); System.out.println("输入的是:" + num); } public static Scanner methoReturn() { //Scanner sc = new Scanner(System.in); //return sc; return new Scanner(System.in); } }
7.6 RANDOM
RANDOM类用于生成随机数据,使用步骤是导包、创建、调用。
获取一个随机的int数字(范围是int所有范围,有正负两种):nextInt()
获取一个随机的int数字(参数代表了范围,左闭右开区间):[0,3)表示的是0-2,也是用nextInt()
package come_four; import java.util.Random; import java.util.Scanner; public class demo04 { public static void main(String args[]){ Random r = new Random(); //产生随机数的方法 //int num1 = r.nextInt(); //System.out.println("随机数是:" + num1); //产生0-9的随机数 //for (int i = 0; i < 100; i++) { // int num2 = r.nextInt(10);//参数代表范围,左闭右开 // System.out.println("随机数是:" + num2); //} //根据int变量n的值 获取随机数字 范围是1-n //Scanner n = new Scanner(System.in); //int num3 = n.nextInt(); //for (int i = 0; i < 100; i++) { // int num4 = r.nextInt(num3) + 1 ; // System.out.println("产生的随机数是:" + num4); //} //猜数字游戏 /* 首先产生一个随机数据并且一旦产生不再变化 需要键盘输入,用到scanner 获取键盘输入的数字 得到两个数字 判断是否太大,如果太大提示太大,如果太小提示太小,猜中则结束 */ int num = r.nextInt(100) + 1; Scanner sc = new Scanner(System.in); while(true) { System.out.println("请输入你要猜的数字"); int guessnum = sc.nextInt(); if(guessnum > num) { System.out.println("太大了,请重试"); }else if (guessnum < num){ System.out.println("太小了,请重试"); }else { System.out.println("恭喜你猜对了"); break; } } System.out.println("游戏结束"); } }