从C++到Java的几点区别
-
java的数据类型
- primitive主数据类型。
boolean 1字节 true/false byte 1字节 -128 ~ 127 char 2字节 0 ~ 65536 short 2字节 -32768 ~ 32767 int 4字节 -2147483648 ~ 2147483647 long 8字节 很大 float 4字节 范围可变 double 8字节 范围可变 - 其中一字节(Byte) = 8bits
-
java程序的编译与运行
//在命令行中javac编译.java文件,会在当前路径下生成 类名.class 文件。
//然后java对应类名运行。
public class MyFirstApp() {
public static void main(String []args){
System.out.print("Hello Java");
}
}
//每个Java程序至少有一个类,每个应用程序有且只有一个main()函数
//Java中所有东西都属于一个类,建立源文件(.java)时,将它编译成新的类文件(.class)真正被执行的是类。
//执行程序代表命令java虚拟机(JVM)去加载这个类,开始执行它的main()
//注意一个.java文件只能有一个public class,如果有,其类名必须与文件名一致。
- 垃圾回收-指针-引用变量-数据结构-运算符
- 不用手动释放堆上的对象。没有指针,声明的对象都需要用new声明在堆上,对象名(也就是C++中的指针名)称为“引用”。
- 引用创建后只能指向(存放)该类的对象(或其子类对象)
- 一旦对象没有引用后,就会被垃圾回收器回收
- 数组也是对象,其中存放的每一个元素都是 primitive主数据类型或者是引用变量(也就是说基本数据类型是直接存放到数组中的。而对象是将其引用变量存放到数组中)
- Java只有按值传递。有时候传递的就是(地址/指针/引用),所以会在方法中改变外面传入的对象。
- 实例变量有初始值,primitive为0,对象引用为NULL。 局部变量没有默认值。
- Java中的数组也是对象,也保存在堆上,其实就比c++多了.length实例变量。
- ArrayList类似数组,有很多方法。
ArrayList<String> myList = new ArrayList<String>(); myList.add("lalala"); myList.add("fafafa"); int size = myList.size(); boolean isIn = myList.contains("lalala"); int idx = myList.indexOf("lalala"); boolean empty = myList.isEmpty(); myList.remove("fafafa")
-
- 短运算符: 与(&&)、或(||)、非(!)都和c++一样。都会出现短路现象
- ArrayList的全名是java.util.ArrayList实际使用时:
- import Java.util.ArrayLis 或者 使用全名。
- 来自java.lang的已经自动导入了。
- 继承和多态
- extends继承类,implement实现接口
- 继承会继承所有public方法和实例变量。只有一种继承
- 继承只能继承一个类,实现可以实现多个接口
- 在子类中,super代表父类。
- 类的所有的方法(函数)都是虚函数。(即能够通过将父类对象赋值给子类引用实现多态)
- 抽象类(类似c++中的虚基类)关键字abstract。其的方法没有内容,只是为了标记出多态而存在。
- Java中有一个终极对象object,所有类都继承于它。它有以下方法。
-
- equals()
-
- getClass()
-
- hashCode()
-
- toString()
-
- implements取代extends, interface取代class接口类似多重继承,但不是真正的多重继承。因为无法在它里面实现程序代码。
- 子类的构造函数会先被调用,但是会在其中先调用父类的构造函数(默认无参)如果想手动指定的话,super()代表父类。所以子类的构造函数最后被执行完成。
- this用于调用本身的其他函数。
- 子类引用可以转换为父类引用,父类不能转换为子类,除非该父类本身是由子类转换过去的。(这里都是指指针/引用)。
抽象类 | 接口 |
---|---|
abstract | interface |
可以有部分方法实现 | 所有方法都不能有实现 |
一个类只能继承extentds一个抽象类 | 一个接口/一个类可以实现implements多个接口 |
抽象类有构造函数 | 接口没有构造函数 |
抽象类可以有main并且运行 | 接口没有main |
抽象类可以有private/protected | 接口方法都是public |
可以说接口在JAVA编程语言中是一个抽象类型,是抽象方法的集合 |
- 生存期(life)可见性(scope)
- 对象被回收情况
- 引用永久离开它的范围
- 引用被赋值到其他对象上
- 引用被设定为null
- 对象被回收情况
- Math方法。是Math类中的静态方法,不需要实例。单例模式
- Math.random()
- Math.abs()
- Math.round()
- Math.min()
- Math.max()
- 被标记为final的变量表示不会再改变了。public static final double PI = 3.14//变量名称最好都大写。
- final用于变量不能被修改,用于类不能被继承,用于方法不能被覆盖。用于实例不能指向其他实例(即使同类),但是可以修改实例内部的值。
- 包装类:将八个基本类型包装成类 Boolean Byte Short Integer Long Character | Float Double
- Java为前面六个建立了常量池(就是大家都指向这块提前分配好的地址)
- Boolean: true false
- Byte:-128 ~ 127
- Character:0 ~ 127
- Short Integer Long:-128 ~ 127
- Float double:没有常量池
- 所以会出现
- Integer a=100;Integer b = 100;assert(a==b);
- Integer c = 128; Integer d = 128; assert(a!=b);的诡异现象
- 常量式的赋值创建会放在栈内存(会常量化)
- Integer a = 10;
- 栈上的数据读取快,容量小
- new对象创建,放在堆内存(不会常量化,不会指向常量池,而是每次都新创建内存区域)
- Integer c = new Integer(10);
- 堆上的数据读取慢,容量大
- 常量字符串也建立了内存池缓存机制
String s1 = "abc";
String s2 = "abc";
String s3 = "ab" + "c";//都是常量,编译器将优化
String s4 = "a" + "b" + "c";//同上
//都相等
//涉及到变量,new对象,都不会优化,否则优化,优化后相等的话则指向统一常量池内存区
- 基本类型和包装类型比较,包装类自动拆箱。但是两个包装类比较不会拆箱,直接比较地址。
int i1 = 10;
Integer i2 = 10;
Integer i3 = new Integer(10);
//i1==i2,i1==i3,i2!=i3.
Integer i4 = new Integer(5);
Integer i5 = new Integer(5);
//i1==(i4+i5),i2==(i4+i5),i3==(i4+i5).因为i4+i5会自动拆箱,结果是int而不是Integer
Integer i6 = i4+i5;
//i1==i6,i2==i6,i3!=i6.
- 一个常见的陷阱:传递指针进去,如果将整个指针指向别的东西,则对外部没有影响。如果修改该指针指向的对象,那么可以修改外部对象。