1、标识符规则(Java语言是区分大小写的)
Java语言的标识符必须以字母、下划线、美元符¥开头,后面可以跟任意数目的字母、数字、下划线和美元符。
(1)标识符可以由字母、数字、下划线和美元符组成,其中数字不能打头。
(2)标识符不能是Java关键字和保留字,但可以包含关键字和保留字
(3)标识符不能包含空格
(4)标识符只能包含美元符,不能包含@、#等其他字符
注意: 字母不局限于英文字母,可以包含Unicode字符集支持的字符,比如中文、韩文等
2、基本类型位数问题
(1)整型:
byte
(1个字节,内存占8位,表数范围:-2的7次方—2的7次方-1)
short
(2个字节,内存占16位,表数范围:-2的15次方—2的15次方-1)
int
(4个字节,内存占32位,表数范围:-2的31次方—2的31次方-1)
long
(8个字节,内存占64位,表数范围:-2的63次方—2的63次方-1)
(2)字符型:char(2个字节)
(3)浮点类型:float(4个字节),double(8个字节)
(4)布尔类型:boolean
注意:
(1)1个字节8位,2的8次方个字符。
(2)直接给出一个整数值默认类型就是int类型。
(3)如果将一个较小的整数值直接(在byte或short类型的表数范围内)赋给一个byte或short变量,系统会自动把这个整数值当成byte或者short类型来处理。
(4)系统允许把一个数值直接赋给另一种类型的变量,这种赋值必须是系统所支持的自动类型转换。但是如果不是系统支持的自动类型转换的话,系统会报错。
byte a=56;
//这个代码是正确的,系统会自动把56当成byte类型来处理
long bigValue=99999999999999999999;
//这个代码是错误的,因为超出了int表示的范围
long bigValue=999999999999999999999L;
//这个代码是正确的,强制使用long类型
int i=1;
byte j=i;
//这个代码是错误的,因为表数范围大的变量不可赋值给表数范围小的变量;
与前面的 byte a=56;形成了对比;
(5)如果使用一个巨大的整数值(超出了int类型的表数范围)时,Java 不会自动把这个整数值当成long类型来处理。如果希望系统把一个整数值当成long类型来处理,应在这个整数值后增加英文字母l或者L作为后缀。通常推荐使用L,因为因为字母l和数字1很容易搞混。
(6)Java语言的浮点类型默认是double类型,若声明一个float型,需要在数字后面加上f或F。
——double a=12.3; float f=12.3f;
(7)Java中无法精确表示部分实数。
由于Java浮点数使用二进制数据的科学计数法表示浮点数,因此可能不能精确表示一个浮点数。
double u=0.9-0.3;
那么输出u的时候,值为0.60000001;
(8)自动类型转换(表数范围小的可以自动向表数范围大的上面转换)
浮点类型float表数的范围比整型long表示的要大(虽然long类型8个字节,float为4个字节),因为float类型可以用科学计数法。
因此表数范围与字节不是正比关系。
float f=1.0f; √ double d=f;√
float f=1.0;×(因为默认是double类型,大的不能给小的)
注意:
(1)
char a='a';b='b';
char c=a+b;
编译时错误的;因为在前面注意的第二点中,byte、short、char互相之间不转换,用时全部自动转换成int类型。即使是只有chat或者short或者byte,也是在用的时候自动转换成int类型。
因此在用a+b的时候,就已经自动转换成int类型,表数范围大的不能赋值给表数范围小的,因此这段代码是错误的。
改成下面才是对的:
char a='a';b='b';
char c=(char)(a+b);
(2)直接给出一个整数值默认类型就是int类型。如果使用一个巨大的整数值(超出了int类型的表数范围)时,Java 不会自动把这个整数值当成long类型来处理。如果希望系统把一个整数值当成long类型来处理,应在这个整数值后增加英文字母l或者L作为后缀。可是,这里int不是可以自动向long转,这是怎么回事呢?
任何一个常量,都是需要给分配空间,需要确定其类型。所以,对于很大的整数,直接赋值给int,jvm不会把这个常量的大的整数自动作为long,是这个意思。int自动换为long,这是指的变量之间赋值的时候,类型的自动转换。就是操作的过程中才能自动转换,但是在初始确定其类型的时候,是不能自动转换。这种情况只是针对超过int范围的整数常量
3、基本类型转换成字符串(字符串是一个类String)的三种方法
Integer i=1;
法一: String s=i.toString();
int i=1;
法二: String j=String.valueOf(i);//想要转换成的类型.valueof
int i=1;
法三: String k=i+"";
转换为字符串的例题
System.out.println(3.5f+"");
//将输出3.5;//因为f只是代表不是double类型,而是float类型的而已
System.out.println(3+4+"Hello");
//将输出7Hello//因为3+4先做运算,之后将其看做字符串;
System.out.println("Hello"+3+4);
//将输出Hello34//因为先将3看成字符串,之后再将4看成字符串;
4、+=与+
+=比+要厉害的多,可以进行强制类型转换。因此:
a+=5等价于a=(byte)(a+5);
5、控制循环次数的变量是不能使用小数,容易出问题
6、class
(1)命名方式
public class 一班学生{}这样的命名方式是对的,因为一班学生符合Unicode语言,包括韩语也可以,但是不提倡这样的命名方式。
(2)构造方法
不能指定返回值类型,名字必须与类名一样
注意:
- void Student其实是有返回值的,只不过返回值是NULL,所以这不是构造方法,仅仅是与类同名的一个普通函数而已。
7、输出的数值必须是已经初始化的数值
String S;
System.out.println(S);
这样会编译出错,因为没有给引用S赋初值,虽然是默认赋值为null,但是是不可以访问的。
public class Teacher
{
public Student s;
Teacher t=new Teacher();
System.out.println(t.s);
}
上面的代码是正确的,为什么呢?是因为已经给类Teacher赋初值了,s是Teacher的成员,所以输出结果为null
public class Teacher
{
public Student s;
Teacher t=new Teacher();
System.out.println(t.s.getname());
}
这段代码是错误的,因为是空引用s是Teacher的成员,所以输出结果为null,但是,并没有给Student赋初值。
8、方法重载
相同名称,但是参数的个数或者参数的类型不同,与返回值是没有关系的,看是否是重载,与返回值无关
9、静态数据成员和静态方法及析构问题
(1)静态数据成员可以通过类直接访问,这个是特殊的,同时也是重要的,只有静态成员可以直接通过类来访问,普通的成员是不能直接通过类来访问的。
(2)java的析构是不定时的,唯有自己通过写一个方法,来控制其析构,虽然有时候用了gc()但是,并非用了gc()之后就进行析构。
(3)静态成员不是只能由静态方法来返回,普通方法也可以返回静态成员
(4)main方法为何必须是静态方法呢?
因为虚拟机启动的时候,自动找入口main,而非先找对象,static是不需要有对象即可使用的,所以main必须为static类型的,否则无法启动虚拟机。
(5)静态方法中只能调用静态成员变量和静态方法吗?
并非是这样的,在没有对象的前提下,确实是在静态方法中,只能调用静态成员变量和静态方法,但是在静态方法中,如果自己创建了对象,并用对象调用普通方法也是正确的
10、内存图的使用与详解
(1)String类存的地方不是堆区,而是数据区。全局,静态和常量是分配在数据区中。
(2)new出来的东西都放在堆区
(3)栈区:主要用来存放局部变量, 传递参数, 存放函数的返回地址。
注意:
(1)java中不是必须先声明后使用,与C语言和c++中不一样,只要有这个函数就可以。
(2)
垃圾回收自动释放的是不再被程序引用的对象。
System是对象,gc()是方法,同时gc()还是静态方法,因为被类直接使用,普通的方法是不能被类直接使用的。
Runtime.getRuntime().gc()其中gc()是getRuntime()返回对象的方法
gc()之后不一定接着回收。
注意:
- finalize方法是JAVA里面所有类中都有的功能,功能是,当垃圾回收器要回收这个对象的时候,会自动调用finalize方法。
- 垃圾回收是依靠一种算法,程序员是无法精确地控制进行控制。
11、JAVA对象
(1)JAVA中除了基本类型以外的变量类型都是引用类型,引用放在栈区。
(2)JAVA里面所有的对象是new出来的,(这个也是与c++中很大的不同点),new出来的东西都放在堆内存中,JAVA里面的所有对象都是动态分配内存的。
Student stu;//stu只是引用,不是对象
12、jre、jvm和jdk
JDK是Java的开发工具,它不仅提供了Java程序运行所需的JRE,还提供了一系列的编译,运行等工具,如javac,java,javaw等。JRE只是Java程序的运行环境,它最核心的内容就是**JVM(Java虚拟机)**及核心类库。
https://blog.csdn.net/qq_33642117/article/details/52143824
13、包
(1)使用包的原因:保证类名的唯一性,解决类名冲突
(2)类中可以使用其它包的所有public类
(3)嵌套包之间没有任何关系
14、继承
(1)所有的类都是Object类的子类
(2)用extends关键字,只能有一个父类
(3)子类是可以赋值给一个父类类型的变量/引用,子类对父类的赋值实际就是子类对象中继承自父类的部分赋值给父类对象,父类引用不能访问子类新增成员。
(4)子类的构造方法必须要调用父类的构造方法
-
借super关键字显示调用父类的构造方法,super必须放在子类的第一行。
-
super关键字不能访问父类中private的成员变量和方法。
-
如果要产生一个继承对象的话,必须先调用父类非private类型的构造方法,然后再用继承对象的构造方法,之后再new出一个对象来。
-
隐式调用:子类构造方法没有显示调用父类构造方法(子类中没有super()),那么父类必须显示提供无参构造方法。
-
显示调用:父类必须显示提供有形参的构造函数
15、equals
(1)stu1.equals()调用的是stu1所指对象(而非引用)中重写的equals方法
pg1.equals()调用的是pg1所指对象中(而非引用)的equals方法
(2)equals中的形参是Object类
16、父类、子类与强制转换之间的关系
(1)强制类型转换的时候,换的是引用的类型
(2)用instanceof判断的是该类所指对象的类型与后面对象之间的关系
(3)是否可以使用某一个变量看的是,这个类的引用类型与变量之间的关系。
(4)子类类型的对象可以赋值给父类类型的引用,父类类型的引用不能访问子类新增成员对象和方法
17、方法重写
1、要求
18、final
(1)防止类被继承,防止方法被重写
(2)引用所指的对象不变即可
https://blog.csdn.net/fighting123678/article/details/82942757
19、类成员的可访问性
(1)何时用default呢?(注意自己不需要加default,因为default是一个关键字)
类只是给本包内的其它类提供一些共享的功能,不需要提供给外面来用,这样的话,就不需要提供修饰符。
(2)想要在别的包中继承某一个不同的包中的类的话,需要下面两步
- import导入类A所在的包(类可以使用其它包中所以public类)
- extends继承类A
(3)想要在同一个包中继承某类的话,需要下面一步 - extends继承类A
20、多态
(1)使用动态多态的条件是什么呢?
- 继承于父类
- 有方法重写,也就是子类中,对父类的某一个方法实现了重新定义。
- 父类引用指向子类对象
(2)父类对象不可以调用子类新建的方法或者是对象,但如果子类重写了父类的某个方法,则此时父类引用调用的是子类方法的内容。
21、abstract类和abstract方法
(1)一个方法如果没有实现的话,不需要有大括号,只需要**public/private/protected+abstract+返回类型+方法名+()+“;”**即可,这个与纯虚函数是类似的。
(2)含有抽象方法的类必须定义为抽象类,虽然定义为抽象类,但是可以声明为public或者private等类型,只需public/private/protected+abstract+class+类名,即可。
(3)如果一个类中有抽象方法或者没有完全实现抽象方法的话,这个类必须写上abstract关键字。
(4)方法内部是不能再定义方法的(也不能再声明方法),但是方法内部是可以调用别的方法(没有返回值类型,只有方法的名称)
(5)抽象类是不完整的,所以不能new对象出来,但是可以有构造函数
22、数组
(1)静态初始化数组
(2)length、length()和size()
- length——数组的属性;(没给数组赋初值的时候也可以使用)
- length()——String的方法;(没给String类赋初值的时候,不能使用,null.length空引用没有指向对象,所以用的时候会报错。)
- size()——集合的方法;
(3)
因为:args是执行这个类的时候,由虚拟机传入并初始化的,但是自己写的时候是必须要初始化的
(4)java数组创建之后不能改变大小
(5)与c++中数组的区别
(6)java中实质上是只有一维数组,多维数组的实质是指向数组的数组,每一个数组所包含数组的长度可以不同
(7)拷贝
所以在打印的时候,第3个的第二行的4会变成100
(8)数组的排序
Array.sort()排序的前提是,对象所属的类实现Comparable接口或者Compare接口
23、接口
(1)无构造方法(与类不同),不能直接实例化也就是new一个对象(与抽象类类似)。
(2)可以通过extends已有接口定义新接口
(3)类继承类的时候用extends,类继承接口的时候用implements
(4)一个类如果要实现接口的话,就必须要实现这个接口中所有的方法,因为接口就是一个规范,如果要实现规范的话,就必须要提供规范也就是接口中提供方法的实现。
(5)一个类可以使用多个无关接口,但是一个类只能继承一个类(也就是只能有一个父类)
(6)
(7)继承两个接口的形式
24、String类
(1)String类的内容不可变,具体说是,这个类所指的对象,一旦初始化之后,就不能改变了。
指向可以改变,但是内容不能改变。
String中的内容不能改,不是因为成员是final类型的,因为,比如final []vlaue,它所指向对象的内容是可以改变的,但是对象是不能改变的。也就是final对象不能变,但是数值可以变。
String中内容不能改,是因为,成员是private类型的,外部访问不到。
(2)String生成对象的方式和内存分配方式
- 可以直接赋值成一个常量字符串,不需要new一个新对象。
- new出的对象才放在堆中,但是常量字符串则放在数据区。
- 在数据区进行赋值的时候,会先找数据区中有没有一样的东西,如果有的话,就直接指向它即可,否则,就在数据区中新开辟内存生成对象。
例如:
25、StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全)
StringBuffer和StringBuilder都实现了toString的重载,但是没有实现equals方法的重载。
26、