转发请在文章中提供本文的链接,谢谢!
一、 数组
1.1 一维数组定义方式
*C++的数组既可以在堆上分配内存(用malloc方法或者new操作符),并由指针来承接,也可以在栈上提前分配(如int a[10] = {0};)。与C++不同,Java的数组都是在堆上分配内存空间,使用new操作符:
int[] arr1 = new int[10];
int[] arr2 = {11,22,33,44,55};
int[] arr3 = new int[]{1,2,3,4,5};
1.2 二维数组定义方式
*C中,在栈上开辟二维数组十分简单快捷,而在堆上调用malloc方法来开辟二维数组时,其过程简直是一场灾难,我们不仅仅需要利用一个二级指针来指向所开辟的指针数组,接下来还需要用指针数组的每个成员来指向所开辟的一维数组,在此期间我们常常还需要考虑到一旦内存开辟到一半出现问题的应对策略……同理,调用free方法对这些内存进行释放的过程也是比较繁琐。而在Java中,虽然开辟二维数组的原理与C基本相同(先开辟指针数组,然后开辟多条一维数组),但其开辟的过程是轻松加愉快的:
int[][] arr1 = new int[5][6];
int[][] arr2 = new int[5][];//注意,这里arr2和arr1的含义是完全不同的
arr2[0] = new int[3];
arr2[1] = new int[5];
int[][] arr3 = {{1,2,3},{4,5},{6,7,8,9}};
二、 面向对象
2.1 面向对象的三大特征
*地球人都知道,封装(encapsulation),继承(inheritance), 多态(polymorphism)是面向对象的三大特征。
*其中封装为我们带来了封装数据与方法的概念,Java的封装方式与C++大同小异,常见区别主要在于构造方法的格式以及析构方法的有无;
*继承则带来了超类与子类的概念,与C++不同,Java并不支持多继承,某种程度上作为相应的补偿,Java引入了接口interface。另外,Java中也并没有C++那样复杂的public、private、protected继承之分;
*多态简单说就是父类引用指向子类对象时,仍可根据其实际调用对象的不同,动态地决定调用哪个函数。在C++中,多态是通过virtual声明虚函数实现的,这样每个对象维护了一个虚函数指针及其指向的虚函数表。而在Java中,无需virtual声明,所有成员方法都可以被重写。
以上对Java中面向对象的特点做了一个简单的综述,后面我们会对这些特性进行详细介绍。
2.2 对象中成员变量和方法中局部变量的区别
* ①在类中的位置不同
* 成员变量:在类中方法外
* 局部变量:在方法定义中或者方法声明上
* ②在内存中的位置不同
* 成员变量:在堆内存(成员变量属于对象,对象本来就是存储在堆内存上的)
* 局部变量:在栈内存(局部变量属于方法,方法执行时执行进栈和弹栈操作)
* ③生命周期不同
* 成员变量:随着对象的创建而存在,随着对象的消失而消失
* 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失(注意,final修饰的变量不在此列中)
* ④初始化值不同
* 成员变量:有默认初始化值
* 局部变量:没有默认初始化值,必须定义,赋值,然后才能使用(请在定义局部变量时赋一个确定值)
2.3 匿名对象
就是没有名字的对象(即没有引用类型去指向它),当只需要调用一次时就可以声明匿名对象,从而节省代码。但是多次调用同一个对象时就不适合使用匿名对象了。
2.4 this关键字
*与python在成员方法第一个参数里显式地声明一个本对象的引用不同,Java、C++默认提供了this关键字,并在非静态成员方法中利用this来调用其它成员方法。
class Person {
private String name; //姓名
public void setName(String name) { //设置姓名
this.name = name;
}
public String getName() {//获得姓名
return this.name;
}
}
2.5 构造方法
*作用是对成员变量进行“初始化”。请注意,这里的“初始化”本质上是赋值。与C++构造方法体的作用相同,而与C++初始化列表在本质上是不同的。C++初始化列表执行的才是货真价实的“初始化”。
*构造方法的生成原则是“需要才会存在”。也就是说:
*①当我们没有定义构造方法时,编译器默认提供一个无参构造方法;
*②当我们定义了有参构造方法时,编译器不提供无参构造方法,除非我们自行定义。
2.6 static关键字
*static可以声明静态成员方法和静态成员变量。经staitc修饰的静态成员变量和方法随着类的加载而加载,优先于对象存在(即使对象从未存在也是如此),并被该类的所有对象所共享(即所有的对象具有同一份静态成员变量)。
*从逻辑上来讲,我们可以认为静态成员方法和静态成员变量是属于类而非对象的。因此,我们可以直接通过“类名.静态成员方法()”以及“类名.静态成员变量”的方式来调用(当然,前提是它们应该是public的)。
*“静态只能访问静态”,也就是说,静态方法只能访问静态方法和静态成员变量;而非静态方法则静态和非静态方法、变量都可以访问。
2.7 静态变量和成员变量的区别
*①所属不同
* 静态变量属于类,所以也称为为类变量
* 成员变量属于对象,所以也称为实例变量(对象变量)
* ②:内存中位置不同
* 静态变量存储于方法区的静态区
* 成员变量存储于堆内存
* ③:生命周期不同
* 静态变量随着类的加载而加载,随着类的消失而消失
* 成员变量随着对象的创建而存在,随着对象的消失而消失
* ④:调用方式不同
* 静态变量可以通过类名调用,也可以通过对象调用
* 成员变量只能通过对象名调用
2.8 代码块
*在Java中,使用{}括起来的代码被称为代码块。根据其位置和声明的不同,可以分为①局部代码块,②构造代码块,③静态代码块,以及④同步代码块。
* ①:局部代码块
* 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
* ②:构造代码块 (初始化块)
* 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
* ③:静态代码块
* 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。一般用于加载驱动。
class Student {
static {
System.out.println("Student 静态代码块");//3,
}
{
System.out.println("Student 构造代码块");//4,6
}
public Student() {
System.out.println("Student 构造方法");//5,7
}
}
class Demo {
static {
System.out.println("主类静态代码块");//1,
}
public static void main(String[] args) {
System.out.println("main方法");//2,
Student s1 = new Student();
Student s2 = new Student();
}
}
输出结果:
主类静态代码块
main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法