核心技术卷

来源:互联网 发布:linux服务器修改密码 编辑:程序博客网 时间:2024/05/17 01:46
java核心技术 卷一
第三章


8种数据类型
整数 int(4个字节) 正好超过20亿
short(2个字节) -32768到32767
long(8个字节) 很大
byte(1个字节) -128到127
浮点数
float(4字节) 有效位数6-7位
double(8字节) 有效位数15位,是float的double倍
char类型
char 用于表示单个字符
boolean类型
boolean 有两个值true和false


使用equals方法检测两个字符串是否相等,一定不能使用==运算符检测两个字符串是否相等(这个运算符只能够确定两个字符串是否放置在同一个位置上)


有时要检查一个字符串既不是空值又不是空串,这种情况下就需要使用以下条件:
if(str !=null && str.length() != 0)
首先要检查str不为null,如果一个null值调用方法,会出现错误


一旦创建了数组就不能改变它的大小,如果经常需要在运行过程中扩展数组的大小,就应该使用另一种数据结构--数组列表(array list)




数组的拷贝,将一个数组变量拷贝到另一个数组变量,这时候两个变量都是指向同一个数组,就是指向的是同一内存区,这两个数组变量任一变量发生改变都会使另一变量发生改变
例如:int[] smallPrimes = {2,3,5,7,11,13};
        int[] luckyNumbers = smallPrimes;
        luckyNumbers[5] = 12;
        System.out.println(smallPrimes[5]);//这时候输出的结果是12


"=="是指变量是所指向的内存区域是不是一样,equals 是指变量的内容是不是一样


Integer与int的区别:int的默认值是0,而integer的默认值是null,通常建议的是使用integer而不使用int,因为比如你不去考试,分数只是null,不能代表是0,虽然实际上是这样做
在web应用开发的时候,如果使用int的话,表单的数据如果为空值的时候就会默认为0,但实际上这里并没有填写任何值,使用integer的话就是null,int不适合web层的表单数据类型


Overload是重载的意思,就是可以有多个方法名相同,但是参数不同的方法,可以根据填写的参数来确定具体调用哪一个方法
Override是覆盖的意思,就是重写,表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法


构造器不能被覆盖,但是可以被重写,就是可以有多个构造器,但他们的参数不一样


面向对象的编程语言有封装、继承 、抽象、多态等4个主要的特征


继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性




List和Map的区别:
List是存储单列元素的集合,存储的数据是有顺序的,可以重复
Map是用键值对来存储的,没有顺序,但是键不可以重复,他的值是可以重复的


List和set的区别:
相同点:都是单列元素的集合,有一个共同的父接口Collection,
不同点:Set里面不可以有重复的元素(不能相等,指向的对象不同内容相同也不可以)
set取元素的时候,只能通过迭代器进行遍历,对每一个元素进行遍历

list集合有先后顺序的,通过add(obj)进行顺序的排队,也可以插队add(index,obj),一个对象可以反复地存储进List集合,但对象只是一个,只是多了几个指向该对象的索引而已
list取值的时候,可以通过get(index)进行取值,也可以通过迭代器进行遍




Map与List和set的区别:
Map是双列集合,有put方法,每次存储都是键值对的形式,不能存储重复的Key,取值的时候通过get(key),取得该key的value值




ArrayList和LinkedList的区别:
ArrayList是采用数组形式进行存储数据的,可以按照索引进行查找数据,查询比较快,但是插入数据比较慢
LinkedList使用双向链表进行存储,插入数据是比较快






第四章:
实例变量是在类的根目录下面,而局部变量是在方法里面的从新定义类型道德变量


final实例域
例如一个类里面的实例变量
private final String name;
这个name一旦被赋值之后就不能再被修改了




静态常量:
静态变量使用的比较少,但是静态常量是经常使用的
例如在Math类中就定义了一个静态常量:public static final double PI = 3.14159...
另一个多次使用静态常量是System.out,它在System类中的声明是
public class System{
public static final PrintStream out = ..;
}


静态方法:
静态方法是一种不能对象实施操作的方法,静态方法不能操作对象,不能在静态方法访问实例域(就是实例变量),
可以使用对象调用静态方法,不过建议使用类名调用


main方法也是一个静态方法,main方法不对任何对象进行操作。事实上,在启动程序时还没有任何一个对象。静态的main方法将执行并创建程序需要的对象


一个构造器里面调用另一个构造器
例如:
public Employee(doule s){
this("这是一个参数",s);
...;
}
当调用new Employee(6000)时,Employee(doule s)构造器就会调用Employee(String s,doule s)构造器




初始化块:
在一个类的声明中,可以包含多个代码块。只要是利用构造器构造新的对象,这么块都会被执行(先执行这些块在执行构造器)

class Employee{
private int id;
priate String name;
...
{
id = 2;//这里就是初始化块
}
//两个构造器
public Employee(String name){
this,name = name;
}
public Employee(){}


}


在这个实例中,无论使用的是哪一个构造器构造对象,id域都会在初始化中被初始化。首先运行初始化块,然后才运行构造器的主体部分
这种机制不是必须的,也不常见。通常,直接将初始化代码放进构造器中。


如果想在类加载的时候就运行代码块,只需要在代码块标记关键字static就行了,
例如
static{
...;
}


使用下面这种方式,可以使用一ava编写一个没有main方法的程序
public class Hello{
static{
System.out.println("Hello,World!");
}
}
在这个类被加载的时候,静态初始化块就会打印"Hello,World!"






包的作用域:
如果一个类没有定义为公有类(就是不是public class + 类名,而是class + 类名)
这样的话只有同一个包中的其他类可以访问
如果这个类中的变量没有标记为private,那就是默认为包可见。这样就破坏了封装性








第五章:




super关键字:
super.getMethod();就是调用父类的getMethod();


super在构造器中的应用:
public M extends {
...;
public M(String n){
super(n);
...;
}
}
使用super调用构造器的语句必须是子类构造器的第一条语句。


如果子类的构造器中没有显式得调用父类的构造器(就是如果没有上面super(n);这一行代码),
则将自动默认调用父类中默认(没有参数的)的构造器,如果父类没有不带参数的构造器,并且在子类的构造器中也没有显式地调用父类的其他构造器,则java编译器就会报告错误




关键字this有两个用途:一是引用隐式参数,二是调用该类其他的构造器。
同样,supper关键字也有两个用途,一是调用父类的方法,二是调用父类的构造器。


在调用构造器的时候,这两个关键字的使用方式很相似。调用构造器的语句只能作为另一个构造器的第一条语句出现。
构造参数既可以传递个本类的其他构造器,也可以传递给父类的构造器。






一个对象变量可以指示多种实际类型的现象被称为多态,在运行时能够自动地选择调用哪个方法的现象称为动态绑定。
例如:一个子类与它的父类,有一个相同的方法,但是这个对象变量可以是子类的类型指引,也可以是父类的类型指引。这是"多态"
它可以选择调用父类的方法,也可以选择调用子类的方法(这两个方法名称是一样的)。这就是动态绑定。






在覆盖一个方法的时候,子类方法不能低于父类方法的可见性,比如,父类方法是public,子类方法一定要声明为public




阻止继承:final类和方法
不能扩张的类被称为final类(就是一个类不想再有子类了)
final class Executive extends Manager{}
一个类中的方法也可以被声明为final。这样子类就不能覆盖这个方法了(final类中的所有方法都是final方法)


前面说过,域(实例变量)也可以被声明为final。对于final域来说,构造对象之后就不能改变它们的值了。不过,如果将一个类声明为final,只有其中的方法自动地成为final,而不包括域。




养成一个良好的编程习惯,在进行类型转换之前,先查看一下是否能够成功的转换
if(staff[1] instanceof Manager){
boss = (Manager)staff[1];
}


包含一个或多个抽象方法的类本身必须被声明为抽象类。
除了抽象方法之外,抽象类还可以包含具体的数据和具体的方法。例如,一个Person类
abstract class Person{
private String name;
public Person(){}
public abstract String getXXX();
public String name(){;
}

一个抽象类可以有抽象方法,也可以有具体的方法。

抽象方法充当着占位的角色,他们的具体实现在子类中。

扩张抽象类有两个方式:一是在子类中定义(定义就是实现该方法)部分抽象方法或者是抽象方法也不定义了。另一个种就是定义全部的抽象方法,这样子类就不是抽象类了。

类即使不含抽象方法也可以将类声明为抽象类。抽象类不能被实例化,但是可以创建一个具体子类的对象。


需要注意,可以定义一个抽象类的对象变量,但是它只能引用一个非抽象子类的实例。




用于控制可见性的4个访问修饰符:
1.仅对本类可见---private
2.对所有类可见---public
3.对子类可见或者是同一个包---protected




Object类中的equals方法用于检测一个对象是否等于另外一个对象。这个方法将判断两个对象是否具有相同的引用。如果两个对象的引用是一样的,那么它们一定时相等的。


如果X是任意一个对象,调用System.out.printlm(x)等于System.out.printlm(x.toString());



泛型数组列表:

ArrayList的类,使用起来有点像数组,但在添加或是删除元素时,具有自动调节数组容量的功能,而不需要为此编写任何代码。
(ArrayList的内部也是数组实现,只是在添加元素的时候,如果内部数组满了,它会自动的创建一个新的更大的数组出来,并将原来的元素拷贝过去)


数组链列表管理着对象引用的一个内部数组。最终,数组的全部空间有可能被用尽(内部数组被用完了)。这时候数组列表将自动创建一个更大的数组,并将所有的对象从较小的数组中拷贝到较大的数组中去。


调用下面的方法可以创建一个可以装100个对象的数组列表,然后调用100次add都不用重新分配空间:
ArrayList<Employee> staff = new ArrayList<Employee>(100);




下面是声明和构造一个保存Employee对象的数组列表:
ArrayList<Employee> staff = new ArrayList<Employee>();
在java7中可以省去后面的类型参数ArrayList<Employee> staff = new ArrayList<>();


可以使用"for each"循环遍历数组列表
for(Employee e : staff){
...;//e就是单个对象元素
}
这个循环和下面代码具有相同的效果
for(int i=0; i<staff.size(); i++){
Employee e = staff.get(i);
...;
}




使用下面的技巧可以一举两得,既可以灵活的扩张数组,又可以方便的访问数组元素。
ArrayList<X> list = new ArrayList<>();
while(...){
x = ...;
list.add(x);
}
执行完上面的操作后,使用toArray方法将数组元素拷贝到一个数组中
X[] array = new X[list.size()];
list.toArray(array);




可以在数组的中间插进一个新的元素,但是这个位置之后的所有元素都要向后移动一个位置。使用带索引参数的add方法 staff.add(n,e);
插进新元素之后,如果数组列表超过了内部数组的容量,那么数组列表就会重新分配空间


同样,可以从数组列表中删除一个元素,staff.remove(n);
位于这个元素之后的所有元素都向前移动一个位置。并且数组的大小减一。




对数组实施插进和删除元素的操作其效率是比较低的。对于小型的数组来说,这一点不必担心。但该=如果数组存储的元素书比较多,又经常需要在中间位置插进,删除元素,就应该使用链表了。




ArrayList中的方法set()与add()的不同
set(int index,T obj):设置数组列表指定位置的元素值,将覆盖这里原有的内容


add(int index,T obj):这里是插进指定位置的元素,这里原有的值是向后移动,并不会被覆盖。




e.getClass().newInstance()
可以创建一个与e具有相同类类型的实例(一个新的实例,就相当于new一个新的对象出来一样)。
newInstance方法调用的是默认的构造器(没有参数的),如果这个类没有这种构造器就会抛出一个异常


将forName与newInstance配合起来使用,可以根据存储在字符串中的类名创建一个对象
String s = "java.util.Date";
Object m = Class.forName(s).newInstance();








第六章:


接口的特征:
接口不是类,不能使用new运算符来实例化一个接口
但是可以声明接口的变量
接口的变量必须引用实现了接口的类对象




可以使用instanceof检查一个对象是否属于某个特定类一样,也可以使用它来检查一个对象是否实现了某个特定的接口。


接口也可以被扩张的,使用extends可以把具有较高通用性的接口到较高专业性的接口。。
例如:
public interface M {
void methodA();
}


public interface N extends M {
void methodB();
}


在接口中不能有实力域或是静态方法,但是可以包含常量。
例如:
public interface ObjectB {
double A = 95;
String name = "A";
}
接口中的域将自动设置为public static final




对象的克隆:
当拷贝一个变量的时候,原始变量和拷贝变量是引用同一个对象。就是说改变一个变量会对另一个变量产生影响。


创建一个对象的新的cope,它的状态与最初的状态一样,但是以后将可以各自改变各自的状态,不会影响到另一个,那就需要使用到clone方法。


clone方法是Object类中的一个方法,用户在编写代码中不能直接调用它,只有Employee类才能克隆Employee类。


如果对象中的所有数据域都属于数值或是基本类型。这样拷贝是没有问题的。
但是如果在对象中包含了子对象的引用,拷贝的结果会使得两个对象共同引用同一个子对象,所以原始对象与克隆对象共享这部分信息。


默认的克隆操作是浅拷贝,它没有克隆包含在对象中的内部对象。


子类只能调用受保护的clone方法克隆自己。


如果一个对象需要克隆,就需要实现Cloneable接口(这里只是做一个标记),否则就会抛出一个异常。





































      
















·

原创粉丝点击