java的入门基本知识

/** */ 文档注释,放在类,模块前面,介绍各部分作用,相当于字典。

java的异常处理机制异常处理

标识符【自己定义的名字,如包名,类名,方法名,变量名等】:由字母,数字,_,$组成,且不能以数字开头,不能为关键字。
驼峰命名—>从第二个单词开始,首字母大写。
除类名第一个单词首字母大写,其他命名规范都是从第二个单词开始首字母大写。

每一个变量由于数据类型不同,所占的内存大小不同---->程序运行起来所占的系统的内存不同。

System.currentTimeMillis();
返回毫秒,与系统当前时间有关。

Java语言类型:

1.基本数据类型:
数值类型:
		整数类型:
				byte  占1字节:-128~127
				short 占2字节:-32768~32767
				int   占4字节:-21亿~21亿
				long  占8字节: -9..(19位)~9..(19位)
		浮点类型:
				float 占4字节
				double占8字节
		字符类型:
				char  占2字节
boolean类型:    占1位,true或false
2.引用数据类型:
类,接口,数组

当直接写一个整数时,java默认是int类型,若想让这个整数原本表示的类型就是long类型----->在整数后紧跟一个l或L(小写L或大写L)

当直接写一个小数时,java默认是double类型,若想让这个小数原本表示的类型就是float类型----->在小数后紧跟一个f或F(小写f或大写F)

当直接写一个整数时,byte和short可以自动转换,如:byte a = 100; short b = 120;(当默认的int类型的值在byte和short的范围内时),double和float没有办法自动转换。如【float c = 12.3;】是无法自动转换成功的。 下处为截图:在这里插入图片描述

数据类型转换:【在将数据类型 全部显示定义 后,与上述情况不同】
小类型到大类型的自动转换:byte–>short,char—>int—>long–>float—>double
(虽然float占4字节,long占8字节,但float表示的数的范围大于long表示的数的范围,,因为浮点型的数据一部分位数表示有效位数,一部分位数表示次方)
浮点型强制转整型,小数部分舍去。

浮点类型存储与运行的不精确性:
浮点数运算:
在这里插入图片描述
实际运行结果:
在这里插入图片描述
原因:double和float的类型的数据在java中本身就是非精确存储的,以float来说,共32位,前一部分用来存储数据,后一部分用来存储次方,采用科学记数法存储,才导致其前一部分的数据部分的存储本就不精确。

++与–运算符在数字前后的区别:
自增自减运算符在后:先进行该算式的运算(输出),再将数字自增或自减。
自增自减运算符在前:先将数字自增或自减(输出),再进行该算式的运算。
例:

int a = 9; int b = 5;
int res1 = a++;//<==>res1 = a; a++;
int res2 = ++b;//<==>b++; res2 = b;
System.out.println(res1);//   输出9
System.out.println(res2);//   输出6

自增与自减元素符的优先级先与赋值符号

int a = 5;
a = ++a + a++; 
System.out.println(a); /* --->输出 12 ;
          ++a ==6,6+6=12(此时还没有使用赋值符号,12此时暂存在内存,还未赋值),
          a++后 a=7(此时使用了自增符号),a = 12(将算式所得的结果 12 赋值给变量 a,
          此时使用了赋值符号,,a = 12 的赋值的时间节点晚于 a = 7 的赋值的时间节点),
          ,所以结果为 12。*/

连等运算(可以但不推荐):
例:

int x,y,z;
x=y=z=6;//<==> z = 6; y = z = 6; x = y = 6;

逻辑运算符:
^ 异或:boolean两边不相同—>true,两边相同—>false
&& 短路与:
|| 短路或: —>短路与不短路(& 与 |)的区别:
当boolean结果可以通过第一个操作数进行判断时,短路运算符后的操作数不进行运算。
例:

int b = 10;
第二个操作数为 (++b > 8) 
则若被第一个操作数短路,println(b);--->所得仍为 10 。

说明:&与| :运算符两边是boolean为逻辑运算符,两边为整数 则为 位运算符。

位运算符:
前景知识:
计算机存储数据时,存储正数—>正数的原码,,存储负数—>负数的补码。。
正数:原码,反码,补码相同
负数:原码(符号位为1)
反码(符号位不变,其余位取反)
补码(反码+1)
位运算符是对计算机存储的这些数据进行的运算,所以要先了解计算机是如何存储这些数据的。
由此—>:
以 & 按位与:对应位都为1才为1
为例:
&两个二进制形式的整数所得的结果:
为正数—>则说明是以原码方式存储,结果本来就为正数,所得即为结果,,为负数—>则说明是以补码方式进行存储,结果本来应为负数,通过补码-1,再除符号位其余取反得到原码—>即得到结果】

| 按位或 :对应位有一个1,就为1
按位取反 (单目运算): 1变0,0变1
^ 按位异或 :对应位 不一样 则为 1.
<< 左移:(高位抛弃,低位补0)
>> 右移 :(高位按照符号位补齐,低位抛弃)
【原来的符号位是0或1,高位就都补成0或1】
>>> 无符号右移 :(忽略符号位,高位补0,低位抛弃)
【没有无符号左移,因为左移时符号位会自动被顶替上,所以不用考虑符号位的符号】
【位移运算 如 9>>3,表示将以原码形式存储在计算机中的9右移3位】

三目运算符:
规则:布尔表达式?表达式1:表达式2
如:

	System.out.println(8>2?"8大于2":"8小于2");

语句块 : 以 { 开始,以 } 结束的成块代码,都被称为语句块。
如:在一个方法(函数)内部也可以使用{ },
在一个方法体内,{}外与{}内的语句仍为顺序执行。
语句块可以访问外面定义的变量,外面的语句无法访问语句块内部定义的变量—>
在一个方法中{}内定义 int a = 1; {} 外无法访问该变量。

if:
特殊用法:

if(5 > 4);  //if条件后紧跟 ; ,空的if方法体,即满足条件后,不执行任何语句。

switch:
switch(x)
{
case x: … ;
break;
default:
… ;} //–>【switch的判断是否相等的条件可以是:整数,字符,枚举,字符串

接收用户键盘的输入:

import  java.util.Scanner;

Scanner Scan = new Scanner(System.in);
int  x = Scan.nextInt();
String s  = Scan.next();

字符串:
字符串无法被修改 是指–>字符串的值无法被修改,但字符串对象可以引用别的字符串
内存区域:栈,堆,方法区(其中还包含 运行常量区)
下图详解:
在这里插入图片描述
栈中存放的基本数据类型(包含该变量及该变量对应的值,如a–>12),引用类型的变量和对应的地址(如 s–>045),

程序通过变量中存储的地址 找到该变量引用的值(位于大区域中的值s1),如图若给引用类型变量s再赋值时,会在大区域产生一个新的值,同时变量s所存储的地址会改变成048进而指向新的值s2。

------------------------------------------------------------------------------

查找子字符串的位置:
s.indexOf(int c);// —>指传递一个char,因为传递char类型会自动转换成int类型,
//传递int类型也会根据其对应的char字符在字符串s中进行查找。
s.lastIndexOf(String str); 等近似方法。。

深层理解String引用类型的"==“与”.equals()"比较。
如:

String Str1 = "创建的字符串变量";
String Str2 ="创建的字符串变量";
String Str3 = new String("创建的字符串变量");
System.out.println(Str1 == Str2); // 输出 true
System.out.println(Str1 == Str3); // 输出 false

原因如下详解:
在这里插入图片描述
字符串常量(“创建的字符串常量”) 在 运行常量区 占据一定的内存空间,变量Str1,Str2及其其中存储的内存地址(054) 在 栈 中存储,其中的内存地址 指向 运行常量区中 存储的常量,【当 赋值Str2 语句的语句执行时,程序查询发现 运行常量区 中已存在相同的常量,于是不再生成新的常量 】,【赋值Str3时,由于new 了一个 新的 String 对象,new 一个对象时会将该 新的对象放置在堆中 】,新的Str3变量及其存储的067地址 位于 栈 中,067地址指向 堆 中的对象,新的对象 中存储的地址(054) 指向Str3 对应的常量。

String属于引用类型,引用类型的变量间的 “==”—>比较变量中存储的地址(引用)是否相等,引用类型的变量间的".equals()"—>比较变量中存储的常量是否相等。

扩充:如 int[] array = new int[50];
则引用类型的array会在栈中存储,new出的50个内存地址成块的存储在堆中,变量array中存储的引用 指向 堆中成块 内存地址。


String s1 =new String("11");
String s2 = new String("11");
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2)); //true

可见每new一次(即使该对象存储的值相同),都会在堆中创建一个对象,该对象的地址存储在栈中的是s1和s2中,==比较这两个不同的引用。
-------------------------------------------------------------------------------

上述,基本类型和引用类型
基本类型存储实际数据,引用类型存储引用(内存地址)。
基本类型变量声明出来不管是否赋值,都在栈中分配内存,引用类型同理,且引用的初始化会在堆或方法区中分配内存。
关于栈:所有 局部变量(在方法中创建的变量都是局部变量) 都存放在栈里面。
引用类型:引用类型还未初始化时,将其 引用 赋为null 是个良好的编程习惯,即使是只赋为null,即可在println中使用。(如: int [] array = null;)

字符串排序:
Str1.compareTo(Str2); // 两个字符串,逐个字符进行比较,遇到相同的字符跳过,直到遇到不同的字符,返回字符(s1 - s2)的值。
若某一字符串是另一字符串的前一部分的子串,则返回Str1.length() - Str2.length() 所得的值。 若完全相等,则返回0;

s.split(String str);—>字符串划分只能使用字符串作为参数
当用于划分的字符串位于原字符串的首部或尾部时:
String str =“sttrsttrs”;
String[] strs = str.split(“s”);
【strs.length == 3,最后划分出的3部分依次是 “”,“ttr”,“ttr”】首划分,尾不划分

探索转义字符"":
例:

String s = "siki.com";
String[] strs  = s.split("\\.");

// 欲使用 “.”划分该字符串,则需要使用“\.",原因如下
“.”在java中属于特殊字符!!,“.”其在java中实际存储时是以“\.”来进行存储的【即实际上在Java中 “.” == “\.”】,所以要想使用“.”来进行划分,需将特殊字符 “.“进行转义来使其真正表示”.”。
进行转义就要使用转义字符"\",但若只使用一个"\",因为"\“是转义字符【即”\“是一个特殊字符】,所以当想使用”\“将特殊字符进行转义时,需再使用一个”\“来将”\“进行转义【即想使用”\“将特殊字符进行转义时,两个”\\“才表示一个”\"】。

规律:传递参数时,“n,s等"都不是特殊字符,而”.“是特殊字符,所以要想传递”.",需在前面加2个"\"。而当想要传递"\n,\s等"为参数时,由于\n,\s为特殊字符,再加上该特殊字符中包含一个"\",所以需在其前面加上3个"\",【才能将特殊字符"\n"转义为普通字符串"\n"】。
设置字符串时,“n,s,. 等"都是普通的字符,不需要转义。
当要在字符串中表示”\n,\s,\.“时,只需要在其前面加上1个”\"【将特殊字符"\n"转义为普通的"\n"字符串,将转义字符"\“转义为普通字符”\"】即可。----->【传递参数时,由于"\\.“等价于”.",要想传递"\.",—>就已经相当于字符串中普通字符".“表示”\.“了,即再在其前面加2个”\",但此时也表示分割符是普通字符串"\n,\s",其可以分割设置的字符串中的"\n","\\n","\.","\\s","\s"】。

-------------------

设置字符串时:

	输入的    n,s,.     <====>  n,s,.  
	输入的 \\n,\\s,\\.  <====>  \n,\s,\.

传递参数时:

    输入的 n,s       <====> n,s
    输入的 \\.       <====> .
    输入的 \\\\n,\\\\s <====> \n,\s
    输入的 \\\\.     <====> \.,\n,\s等
    				-->其可以分割设置的字符串中的"\\n","\n","\\s","\s","\\."
    输入的 \\\\\\.   <====> \.

Java的API含义:
API <==>应用接口

随机数
除了java默认导入的包自带的Math.random()来生成随机数之外,

import java.util.Random;
Random r = new Random();
r.nextInt(10);

random.nextInt(int x);
如:其中若参数为10,则随机生成0~9之间的整数(左右包含),即随机生成0至(x - 1)之间的整数。

数组:
数组的3种创建:
int[] array = new int[50];
int[] array = new int[]{1,2,3,4,5};
int[] array = {1,2,3,4,5};

数组间引用的赋予

int[] a = {1,2,3,4,5};
int[] b = null; //此时b的引用是null,null的指向是空指向
b = a;  
System.out.println(a[0]+" "+b[0]);
b[0] = 800;
System.out.println(a[0]+" "+b[0]);

运行结果:
在这里插入图片描述
原因:
在这里插入图片描述
代码

b = a;

是将a中存储的引用(指向的内存地址)赋给b,使b中原来存储的null变成 a中的引用。
而代码

b[0] = 800;

是程序根据 b 的引用改变 其 指向的内存地址中的数据,而a指向的也是同一个内存地址中的数据,所以即a[0]也被更改。

关于深究上述程序中没有使用new的{1,2,3,4,5}是否位于运行常量区:
在这里插入图片描述
如果{1,2,3,4,5}位于运行常量区,则b变量在赋值引用时,发现指向的数据已经存在于运行常量区,则b中的引用会与a中的引用相同—>都是运行常量区中该数据的内存地址。
而实际运行结果是:
在这里插入图片描述
结果中:a与b中存储的引用(指向的内存地址)不相同—>说明即使是没有使用new而创建的{1,2,3,4,5}是位于堆中的,{1,2,3,4,5}相当于一个新的对象。
(此点与String的new与不new不同,也打破了只有new才会在堆中创建的错误想法)

使用指定值部分填充数组:

import java.util.Arrays;

在这里插入图片描述
支持多种数据类型的数组的填充。

**二维数组:**在使用中理解成是一维数组的一维数组
3种声明方式:

//第1种,固定数组规模
int[][] arrays = new int[10][50];
//第2种,根据括号中一维数组的长度自动形成,声明形式固定
int[][] arrays = {{1,2,3},{0,1,2,3,4},{1}};
//第3种,为 新开辟内存的一维数组(如下刚开始是10个null),
//随后为各个一维变量赋予引用,,声明形式固定
int[][] arrays = new int[10][];
arrays[0] = new int[]{1,2,3};
arrays[1] = new int[]{0,1,2,3,4}

方法调用对数据产生的影响:
方法调用时,会在栈中占据一定的内存空间【理解为:调用方法时,方法有自己的一个栈,这个栈用来存储方法调用的时候它所需要的一些内存的】。方法调用过后,其所占用的内存空间会被删除掉。
例:

public static void main(String[] args){
//传递基本类型变量,传递的是值,方法对[栈中方法的空间中的变量]的值更改--->
//      对原变量不产生任何影响,输出 10
int a = 10;
methodA(a);
System.out.println(a);

//传递引用类型变量,传递的是引用,方法通过引用对值进行更改--->
//      使原变量对应的值改变,输出100
int[] b = {10};
methodB(b);
System.out.println(b[0]);

//传递引用类型的变量,传递的是引用,对[栈中方法的空间中的变量]赋予新的引用--->
//       对原变量不产生任何影响,输出10
int[] c = {10};
methodC(c);
System.out.println(c[0]);
}

public static void methodA(int a){
a = 100;
}
public static void methodB(int[] a){
a[0] = 100;
}
public static void methodC(int[] a){
a = new int[10];
}

methodA()的执行:
在这里插入图片描述
methodB()的执行:
在这里插入图片描述
methodC()的执行:
在这里插入图片描述

方法重载:
方法名一样,参数不一样–>即称为方法重载

成员变量:
类中定义,【因为是成员变量,所以只在堆中占用内存!!
成员变量定义时并不占用内存,,new时才开始在堆中占用内存,
【堆中new出来的对象什么时候被 销毁(标记为未使用)
当没有任何变量引用该对象时】,
有默认值,不必须初始化,

局部变量:
方法中定义,
方法开始调用时,开始在栈中【若是引用类型,也会在堆中占用一些内存空间】占用内存,方法调用结束(方法返回)时,被销毁
无默认值,必须初始化

理解为,每个方法运行时都会在栈中占用其独有的一块内存,其中的局部变量在其专有的空间中。

垃圾回收机制:
java虚拟机不断检测 堆中的对象,一旦其不被任何 其他对象(包括栈中的对象(变量) 和 堆中的其他对象) 所引用(指向),就会被销毁。

private:
成员(属性或方法)被设置为private后将只能在该类内部使用。

构造方法:
只有当new对象的类中没有任何的构造方法时,才会为其提供默认的无参构造方法。
当new对象的类中存在任何构造方法,都不会为其提供默认的无参构造方法。

封装:
设置set,get方法。

static关键字(静态修饰符):
1.在内存中的静态变量的表示形式(其中country是Person类中的成员变量):
在这里插入图片描述
修饰成员变量表示静态变量,静态变量是所有对象公用的,同一个类的同一个静态变量只占据一份内存。
2.在内存中的静态成员方法的表示形式(其中show是Person类中的成员方法):
在这里插入图片描述
static修饰成员方法表示静态方法,静态方法里面只能直接访问静态变量。
因为如果在静态方法中直接访问某一变量,则不知道访问的是哪个对象的成员变量?所以在静态方法中只能直接访问该类的静态变量(不带变量名前缀,且该类只有一个该变量不会引起歧义)。。
但在静态方法中可以访问该类的非静态变量,只需为某非静态变量加前缀实例名即可。

static作用:工具类的创建—>工具类中含有大量static方法,因此使用时不需要先new对象,可以直接用类名作前缀,使用时方便快捷,(如Arrays类和Math类)。。将工具类的构造方法private,可以防止使用其中的方法时使用复杂的方式(先实例化再使用方法)。

使用String[] args:
在运行java程序时,可以在后面跟上参数(空格隔开),参数直接传递到args数组中。
在这里插入图片描述
在这里插入图片描述
帮助文档的生成:
使用/** */文档注释为类和方法进行文档注释。
在这里插入图片描述
使用【javadoc -d 注释文档名 用于生成注释文档的java文件】
生成注释文档。。
在这里插入图片描述
静态代码块:
静态代码块 static{} 在类加载的时候执行,如类中(不是在方法中)包含一个静态代码块。
在这里插入图片描述

继承:
1.当多个类含有相同的属性和行为时常考虑使用继承 extends (单继承)
2.当子类中的变量名与父类重名时,采取就近原则选取变量
3.当没有显式的调用(使用super调用)父类里的构造方法时,默认会调用父类里的无参构造方法,对父类中的属性进行初始化。显式调用时,super()必须是子类构造函数中的第一条语句,来调用父类的构造方法。【即通过子类的构造方法构造子类对象时,一定会调用父类里的构造方法】
4.对this();的调用和对super();的调用必须是构造器中的第一个语句。
5.方法重写(方法覆盖):
子类中的方法重写不能降低父类中被重写方法的访问权限!
6.重写与重载的不同:
重写:子类与父类之间,,方法名,参数,返回值 都相同。
重载:同一个类中,,方法名相同,参数不相同,返回值不要求。
7.final
final类:不能被继承
final方法:不能被重写
final变量:时恒定的自定义常量。

包 package:
定义包名:package xx.xx.xx
在DOS上对带包名的类进行编译和执行:

编译:  javac -d . 类名.java
执行:	java 包名.类名

如:hello类(带package且import了world类),world类(带package),要执行hello类-------> 必须先编译world类,才能成功编译hello类,最后可以执行hello类。
调用main方法,可以使用world.main(null);

访问权限修饰符:
类 :只有public和default(不使用修饰符),,控制是否可以在包外访问。
成员(变量和方法):
public : 所有地方。
private :只有位于同一个类才能访问。
default: default表示能够被同包的访问。如果子类和父类是在同一个包里,则子类能够访问,否则不行。
**protected:**与default范围稍大,子类与父类不在同一个包也可以访问到父类中的protected成员,
但若用 父类对象名.变量名 进行访问则:
在这里插入图片描述
可以直接在子类中使用 变量名(父类中的变量名) 进行访问!!成功!!
在这里插入图片描述

内部类与外部类:
外部类 与 内部类之间的关系<==>宿主 与 寄生虫 之间的关系
一个宿主可以含有多个同种 (或不同种)的寄生虫,所以宿主 不认识 寄生虫,寄生虫 很容易就识别出 宿主。
如:外部类outer和内部类inner
inner类中不能存在static成员

outer类与一般java类一样只能用public和default 修饰,但inner类相当于outer的一个成员,可以使用的访问权限修饰符有 public,protected,default,private,static【其中若为private则不能在outer类的外部访问,若没有用static或private修饰则可以访问到】。

outer类无法访问(指:直接访问:不带对象名前缀)inner类的任何类型成员,inner类可以直接访问outer类的任何类型成员(包括private修饰的成员)

inner类的对象在outer类以外的其他类中的正确创建方法:
新的inner对象 = 新的outer类.新的inner类

1.Outer.Inner in = new Outer().new Inner();
2.Outer out1 = new Outer();
  Outer.Inner in = Out1.new Inner();

当inner类与outer类中的全局变量重名时,在inner类依据就近原则访问到的是inner类的变量(即使使用了this前缀),若要在inner类中访问到outer类的同名变量,则使用

outer.this.变量名

进行访问,即 【外部类类名.this.变量名】。

局部内部类:
一般的内部类是在outer类中且在其方法外定义的,局部内部类是在outer类的任意方法中定义的,且只能在定义其的方法中访问到(进行使用)

继承和多态:
正是因为 继承,才可以多态。

父类People  拥有方法:eat()
子类Teacher 拥有方法:eat(),teach()
子类Student 拥有方法:eat(), study()

则多态是指:
People p = new Teacher()
使用子类的构造方法构造一个父类对象p,则对象p所占内存空间是一个Teacher的内存空间,由p.eat()调用的方法是Teacher中重写的方法【且该方法在父类People中必须存在】。
若想调用Teacher特有的teach()方法,则:((Teacher)p).teach() 进行调用,且p的本质是Teacher【因为由其构造】,所以不能使用上述方法调用Student中的特有方法。

抽象类:
abstract前缀:
1.抽象类中可以没有抽象方法,但抽象方法只能存在于抽象类中
2.不能使用抽象类的构造方法进行类的实例化【但可以在在抽象类中写构造方法?为了方便子类调用继承而来的构造方法来对继承的属性进行初始化】
3.抽象类的子类继承该抽象类【为实现父类中的抽象方法或调用方法】后,则子类中直接拥有了父类中的抽象方法且必须对这些abstract方法赋予方法体,否则是残缺的类(含abstract方法)从而不能调用其构造方法实例对象。
4.abstract类A,其子类B,则可以:

A a =new B();
a.xx();

来调用B中【重写或实现】的方法(A中需拥有该方法),或A中本来就有的非abstract方法。
5.抽象类可以继承抽象类,知道一个完整的类继承了其父抽象类为止,则该完整的子类必须实现父抽象,爷爷抽象等抽象类中直到其父抽象类中没有实现的所有抽象方法。

接口:
接口里只能包含抽象方法–>是完全抽象的类,里面没完整方法
通过接口定义一些功能,其他类通过实现该接口来拥有并扩展功能。
接口可以被实现,也可以被另一个接口继承【接口中可以有变量和抽象的方法
接口可以被抽象类实现,也可以被具体类实现
Java单继承,多实现

多实现的情况:
interface中默认的方法 访问权限修饰符 是public,在其子类中的实现方法至少为public。。
如interface的A和B,和实现其方法的C:
在这里插入图片描述
在这里插入图片描述
采用的多态方法构建interface的对象时,使用new C()的构造方式进行构造,则其本质就是类C,但由于构造出的实例变量是A a,则会调用类A中的方法,之后将该实例变量强制转换为某类X,就会调用某类X的方法,,同样的下面看 关于父子类的方法调用

public class Test39 {
public static void main(String[] args) {
Base a = new DerivedA();
a.test();//调用类Base中的方法,但test()被重写了,输出DerivedA中的test()
a.testBase();
System.out.println(a);//test.DerivedA@15db9742

Base b = new DerivedB();
b.test();//调用类Base中的方法,但test()被重写了,输出DerivedB中的test()
b.testBase();
System.out.println(b);//test.DerivedB@6d06d69c

((DerivedA)b).test();//调用类DerivedA中的test(),但DerivedB将其重写了,输出DerivedB中的test()
((DerivedA)b).testBase();//调用类Base中的方法,原因是DerivedA中继承了该方法

((Base)b).test();//调用Base的方法,被DerivedB重写则调用了DerivedB的test()
((Base)b).testBase();//调用Base的特有方法

((DerivedB)b).test();//调DerivedB
((DerivedB)b).testBase(); //用强转DerivedA相似
}
}

class Base{
	public void testBase() {
		System.out.println("Base特有的方法");
	}
	public void test() {
		System.out.println("Base ");
	}
}
class DerivedA extends Base{
	public void test() {
		System.out.println("DerivedA ");
	}
}

class DerivedB extends DerivedA{
	public void test() {
		System.out.println("DerivedB ");
	}
}

与接口类方法调用规则的新鲜之处在于,子类进行调用时,还可以调用从父类继承的方法;父类进行调用时,若其本质子类中重写了该方法。则调用其本质子类中的该方法。

匿名内部类:
一个 接口interface 或 抽象类 Product类 ,使用一个实现其的子类 或 继承其的子类,该子类没有类名其实现完方法后立刻被调用,则该子类为匿名内部类。

interface Product{
	String getName();
}
在其他类的方法中:
System.out.println(
	new Prodect(xxxx){
		public String getName(){
			return "Apple";
			}
		}.getName()  //此处没有  分号!
	);

其中的匿名内部类也可作为参数传给 Product p 的参数类型,匿名内部类构造方法中的xxxx可以直接传给 抽象父类Product 中的构造方法进行子类的初始化。。

Object类:
其中含有的 toString() 方法默认的作用是取得对象的内存地址(引用),含有的equals()方法默认是将对象的内存地址进行比较,
而String中的equals()方法已经被重写过了,所以比较时比较的是String的值。若对自己自创的类调用equals()方法想比较值,需要自己重写equals方法。

Scanner:
如Scanner的hasNextInt()判断用户输入的下一个是不是整数,通过对hasNextInt(),next(),nextInt()进行调用,可确保输入的值一定是一个整数,否则不接取。

StringBuffer:
.append()调用完返回的是自身—>可以链式编程(不断调用.append()方法 ),返回的引用与原引用相同。
StringBuffer有初始容量,占满后会申请一个更大的内存空间,引用指向这个更大的内存空间【新的内存空间是原内存空间的2倍以上】,原内存空间中的数据被复制到新的内存空间中。
初始容量capacity由初始数据量大小或设置的capacity决定,扩容后的大小与原容量大小有关系。
String不可变【不能通过append在原内存空间里直接衔接或delete直接删除部分字符串】,StringBuffer与StringBuilder可变。
字符串的存储,在内存中,JDK9之前使用char数组存储,JDK9中使用byte数组存储(占用的内存空间更小)。

StringBuffer和StringBuilder的联系:
都可创建一个可以修改的字符串,使用起来基本相同【包含的函数基本一样】。
不同:
StringBuffer线程安全,但性能略低
StringBuilder线程不安全但性能略高
所以在单线程的程序中一般使用StringBuilder,在多线程的程序中一般使用StringBuffer。

Arrays:
Arrays.sort()对数值型数组进行默认的升序排序。
Arrays.binarySearch(数组a, key值) 使用二分法搜索指定的key值,必须在此调用前使用sort()方法对a数组进行排序
如果没有排序,则结果是不确定的()【小的数值可以查找到但index按升序sort后的index且忽略相同值占用的index个数,大的数值返回未知负数】,
若a中包含多个key值元素,则无法保证找到的是哪一个【排序后可保证能找到,但不一定是升序中第一个符合的index】。

Math:
Math.E 自然底数
Math.ceil() 向上取整 |Math.floor() 向下取整 |Math.random() *控制个数,+控制范围

**BigDecimal:**大小数
//此处传递的精度是不受限制的,只推荐这一种声明方式
BigDecimal number = new BigDecimal(“0.00000000001”);
使用 BigDecimal.valueOf(double数) 声明时函数会对其精度进行调整更精确,但不推荐。
BigInteger:大整数,用法与BigDecimal相似。

Date和Calendar:
Date存在缺陷,其中大部分方法被废弃,Calendar是Date的升级版。
Date d = new Date(); print(d);–>输出当前时间
Calendar calendar = Calendar.getInstance(); print(calendar);
---->输出当前时间(较上面的 d 更加详细)
print:calendar.get(Calendar.YEAR); —>输出当前年份
其他常量参数可输出calendar的其他信息!

拆箱和装箱:
拆箱:基本类型包装类对象—>基本类型
装箱:基本类型 ---->包装类对象
如:

Integer i =100;//装箱 等价于 Integer i = Integer.valueOf(100);  自动的装箱过程
i = i + 100;//先拆箱后装箱 <==> i = i.intValueOf() +100; 拆箱得200后再装箱为对象 
System.out.println(i); //toString早被重写过了,输出200
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章