左移num位,丢弃最高位,0补最低位,如果移动的位数超过了该类型的最大位数,则编译器会对移动的位数取模(根据被移位数的类型而定模的大小)。
运算规则:
a.当左移的运算数是int类型时,每移动1位它的第31位就要被移出并且丢弃;b.当左移的运算数是long类型时,每移动1位它的第63位就要被移出并且丢弃。
c.当左移的运算数是byte和short类型时,将自动把这些类型扩大为int型。
d.在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方
13、右移运算:
value>>num:
符号位不变,左边补上符号位;运算规则:
a.按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1;b.当右移的运算数是byte和short类型时,将自动把这些类型扩大为int型。
14、三目运算符(条件表达式):
*"y:
z;表示*为真时,表达式的值是y的值,否则取z的值。
int*=1,y=2,z=3;inti=*<0"y:
z;则i的取值就是3.
15、java中提供了四种转移语句:
break、continue、return、throw
break:
在Java中,break语句有3种作用。
第一,你已经看到,在switch语句中,它被用来终止一个语句序列。
第二,它能被用来退出一个循环。
第三,它能作为一种“先进”的goto语句来使用(breaklabel;标签label是标识代码块的标签。
当这种形式的break执行时,控制被传递出指定的代码块。
被加标签的代码块必须包围break语句,但是它不需要是直接的包围break的块。
这意味着你可以使用一个加标签的break语句退出一系列的嵌套块。
但是你不能使用break语句将控制传递到不包含break语句的代码块)。
16、continue:
类似break,不带标签的continue是终止当前循环结构,转而直接进入下一轮循环。
而continuelabel;则是把程序直接转到label所指向的那一个循环结构的下一轮循环,而不管被它嵌套的及continue语句所在的循环结构运行到了哪一轮。
17、方法的调用及参数的传递:
一个是传值(要**际参数必须是简单类型的变量),一个是传递地址(数组)。
18、类与对象:
类是对对象的抽象,而对象是对类的具体化或实例化。
19、类头说明:
类名第一个字母大写并体现该类的功能或特征。
类的修饰符分两种:
一是访问控制符,如public;一是类型说明符,类型说明符只有两个:
abstract和final。
20、类的访问控制符:
一个是public,可以被所有的类访问和引用,其他包用import语句引入后可调用;一个是默认的,也就是没有控制符,也称为友好的friendly,包中的类能用——而不能被其他包中的类访问或使用(import引入也不行)。
注意:
import语句引入的类必须是public修饰的类,Java规定一个.java文件可以有多个类,但必须有一个而且最多有一个public类,因而文件中的其他类只能是友好访问控制符。
21、属性和方法的访问控制符:
public、private(私有访问控制符,只能被该类自身所访问或调用)、protect(保护访问控制符,它可被同一个包中的其他类、不同包中的该类的子类及自身调用)、privateprotect(只能被该类自身及该类的子类访问和引用)、默认访问控制符(具有包内访问性,只能被同一个包中的其他类访问或引用,不在同一个包中的类不能访问它,即使用import语句引入也不行)
22、static:
只能修饰属性和方法,修饰的属性和方法不用实例化,可以用类直接调用。
23、多个修饰符放在一起使用:
abstract不能与final共同修改一个类;abstract不能与private,static,final和native共同修饰一个方法;abstract类中不能有私有属性和方法。
24、另一种创建对象的方法:
假设一个类名为Te*t,它有一个方法名为print(),则可以直接用下面的语句创建对象并其方法:
newTe*t().print();不过这个对象是无名,所以不能被再次调用。
25、构造函数:
构造函数名字必须与类名完全相同,没有返回值也不用void指明,还可以通过重载实现不同的初始化方法。
26、Java允许类的嵌套:
因此类的默认访问控制符有两个:
一个是友好类default,一个是类中类,一个友好类编译后能后生一个独立的.class文件,如Input.class,而类中类却产生Judge$Imput.class,所以只能被包含它的类使用。
27、命令行参数:
main()方法是通过Stringargs[]这个字符串数组来接收命令行参数的。
28、继承:
一个子类只能继承一个父类,这样继承关系就形成了一棵树。
继承能够使子类拥有父类非私有的属性和方法。
子类通过super来调用父类的属性和方法。
29、多态:
指一棵继承树的类中可以有多个同名但不同方法体以及不同形参的方法。
分两种情况——覆盖和重载。
覆盖是在子类中直接定义和父类同样的属性和方法,而重载是指在同一个类定义中有多个同名的方法,但有不同的形参。
覆盖:
子类与父类的关系,是在子类中直接定义和父类同样的属性和方法,但重新编写了方法体,即子类与父类的形参与返回值都相同,但内部处理不同。
通过调用它的对象来决定调用哪个方法。
重载:
同一个类内部多个方法间的关系,是指在同一个类定义中有多个同名的方法,但不同的形参,而且每个方法有不同的方法体,调用时根据形参的个数和类型来决定调用的是哪个方法。
通过形参表来决定调用哪个方法。
30、在Java技术中,另一个必须要求有重载存在的原因是构造函数。
31、继承了父类的属性表示子类被创建时另外开辟了新的空间来存储从父类继承而来的属性,其初值应该是父类中属性的初值,但之后双方的相同属性彼此相互独立。
32、final修饰的方法不能被子类覆盖,但可以被重载。
abstract修饰的方法必须被子类覆盖。
33、this的使用:
this关键字(只能在方法内部使用)可以为调用了自己的方法的那个对象生成相应的地址,可以像对待其他任何对象地址一样对待。
publicclassLeaf{
privateinti=0;
Leafincrement(){
i++;
returnthis;//将当前对象的地址作为返回值返回
}
voidprint(){
System.out.println("i="+i);
}
publicstaticvoidmain(String[]args){
Leaf*=newLeaf();
*.increment().increment().increment().print();//多次调用方法//increment(),返回的都是对象*的地址,i值表示调用次数
}
}
34、super的作用:
它并不是父类对象的地址,它专门用来指代父类,也就是说super的含义是被修饰的属性和方法将使用父类的定义,而非子类本身的定义,因此子类的对象想使用它父类中的同名属性和方法时,就可以使用super。
35、构造函数:
如果定义了多个构造函数,创建对象时必须使用其中之一,因为系统不再定义默认的空构造函数了。
构造函数的简化(调用):
用构造函数间的调用可以实现定义的简化,就是先调用定义好的构造函数完成部分属性的初始化,再加上其他属性的赋值。
publicclassLeaf{
privateStringlname;
privateintlnum;
Leaf(intnum){
lnum=num;
}
Leaf(int$num,String$name){
this($num);//调用上一个构造函数,等同于lnum=$num;
lname=$name;
}
publicstaticvoidmain(String[]args){
Leaf*=newLeaf(20,"good");
System.out.println("lnum="+*.lnum+"lname="+*.lname);
Leafy=newLeaf(22);
System.out.println("lnum="+y.lnum);
}
}
调用其他构造函数时,必须加上this代替函数名,但这时的this不代表地址,只用来表示构造函数的名称,也就是类名;注意要在实际参数名前加上$作为开参名,这样既区别于实际参数名,又能反映形参的含义。
构造函数的继承:
A、子类只能继承父类的默认构造函数,即无形参构造函数,并且在创建对象时先调用这个构造函数对对象进行初始化,再调用子类自己定义的构造函数。
B、如果父类没有默认构造函数,子类将不能从父类继承到任何构造函数,并且子类也不能定义自己的无参数构造函数。
C、如果子类想调用父类的非默认构造函数,必须使用super来实现。
例如调用父类的构造函数并加入自己的定义:
NormalStudent($stuFlag,$sName,$sSe*,$reduceFlag){
super($stuFlag,$sName,$sSe*);//此处调用的是父类的构造函数对形参$stuFlag,$sName,$sSe*初始化。
reduceFlag=$reduceFlag;
}
D、子类的构造函数的形参表只能使用父类构造函数中用过的形参表,或者是对它的扩展。
例如父类的构造函数只有一个:
Super(inti,Strings){……},则它的子类只能定义这样的构造函数:
subbie(inti,Strings,charc){……}等。
36、最终类成员A用final修饰的方法是不能被该类的子类所重载的方法。
B、用final修饰的简单变量相当于常量,不管这个变量是属性还是自变量,这时相当于编程者用一个名称来代替一个常量。
如果类的属性是常量,则它的各个对象的这个值一定相同,所以final通常和static放在一起修饰属性,以节省内存空间;另外final的修饰的简单变量通常是所有字母大写,以表示它是常量。
37、静态变量、动态变量区别
A、对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。
B、对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。
38、对象在继承关系中的改变:
A、子类实例可以被当作父类的一个对象使用,而父类实例不能被当作子类的一个对象使用。
子类对象可赋予父类对象,父类对象赋予子类对象则出错
B、如果一个父类对象通过赋值指向的地址是子类对象所在的地址,按照前一条规则,这个对象仍然是父类的对象。
但它可以通过强制类型转换变成子类对象,这种转换只能用在对象间赋值时,不能单独使用强制转换。
以上规则可以这样理解:
子类对象所占的内存在一般情况下比父类对象所占的内存空间大,父类对象中的成员都可以在子类对象的地址中找到对应部分,所以可以把子类对象当作父类的一个对象用。
而相反时,子类对象的成员并不一定能在父类对象地址中找到对应部分,这样就可能造成成员丢失。
而强制类型转换则是因为父类对象本身就与子类对象的地址相对应(从子类转换而来),当然可以把这个对象转换成子类的对象,而不造成成员的丢失。
publicclassObjectConvert{
publicstaticvoidmain(String[]args){
SuperClasssuperA=newSuperClass(),superB;
SubbiesubA=newSubbie(),subB;
//用子类对象作为实际参数传递给应是父类对象的形参
(newObjectConvert()).useSubAsSuper(subA);
superB=subA;//把子类对象赋予父类对象
System.out.println("superB.get*()"+superB.get*());
//如果输出中仍用方法getY()将出错。
//System.out.println(superB.gety());
//subB=superA;//把父类对象赋予子类对象将出错
//把指向子类对象地址的父类对象superB强制转换成子类对象,并赋予subB
subB=(Subbie)superB;
System.out.println(subB.get*()+""+subB.getY());//子类对象还相当于是原来的子类对象subA
}
publicvoiduseSubAsSuper(SuperClass*){
System.out.println(*.get*()+"!
!
!
!
");
}
}
classSuperClass{
privateint*=100;
publicintget*(){
return*;
}
}
classSubbiee*tendsSuperClass{
privateinty=200;
publicintgetY(){
returny;
}
}
39、抽象类:
抽象类的属性和方法是它的子类的公共属性和方法的集合。
A、用abstract修饰的方法是抽象方法,所有的抽象方法都必须在抽象类中,抽象方法只有方法头而无方法体。
定义格式如下:
abstract返回值类型方法名([形参]);
B、抽象类可以包含抽象方法和一般方法,继承它的非抽象子类必须实现其所有的抽象方法(注意是覆盖而不是重载),对于抽象类中的一般方法的继承和普通的继承一样,只要该方法是非private的就可以继承。
C、抽象类的实例:
抽象类不能有实例,但有一种情况例外,就是定义一个抽象类的对象名(引用)指向它的非抽象子类的对象。
这也就是38(B)中介绍的情况,这时的抽象类实例只含有父类所有的方法,而没有子类新增加的方法。
可以这样理解:
一个对象名或方法名相当于一个指针,父类的对象指向了子类的实例对象,因此父类对象的方法找到了指针的目标,就是子类对象中的同名方法,而对于子类对象中私有的方法C(),父类对象中没有指针指向C(),也即父类对象根本不知道有方法C()的存在,所以父类对象不能调用子类对象方法C()。
D、抽象类可以有抽象方法也可以没有抽象方法;但是如果一个类有抽象方法,那这个类只能定义为抽象类。
E、如果是抽象类实现一个接口,则抽象类中可以不具体实现接口的方法(保持其抽象性),而由其子类去实现。
40、接口:
接口在语法上和类很相似,它的属性都是常量(用final修饰),方法都是抽象方法(abstract),没有方法体,接口间也可以形成继承关系。
定义:
[public]interface接口名[e*tends父接口名1,父接口名2,……]{
[publicstaticfinal]属性数据类型属性名1=值;//必须给出属性值
……
[publicabstract][native]返回值类型方法名(形参表)[throw例外名列表];
……
}
说明:
1、puiblic表示它可以被不同包中的类或接口使用,没有用public表示它是友好的(default),具有包内访问性。
Interface的修饰符只能为public或默认(default)。
2、子接口将继承所有父接口的所有属性和方法
3、接口的属性必须是publicstaticfinal(静态常量)修饰的,这是被系统默认的,所以可以不写,但一般写出final(所以接口的属性必须给出属性值)
4、接口的方法系统默认为publicabstract的,一般不写修饰符
5、一个接口可以没有任何接口体,但大括号不能省略,这种接口一般是接口继承结构中一个最顶层的父接口
接口与抽象类的区别:
接口中不能有非抽象的方法,但抽象类中可以有
一个类能实现多个接口,但只能有一个父类
接口与继承无关,所以无关的类可以实现同一个接口。
接口的实现:
必须在类的定义时用关键字implements来声明
一个类声明实现*个接口后必须实现该接口的全部方法(包括该接口的所有父类的方法),被实现的方法和接口定义的方法有完全一样的方法名、返回值和形参表。
被实现的方法的访问控制符必须显式地使用public修饰,因为接口的方法都是public的。
41、适配器:
当我们只需要使用*个接口中的少部分方法时,可以继承与之相对应的抽象类(抽象类不用实现所有的方法..)。
java类库为所有的接口都提供了与之相对应的抽象类,我们称之为适配器。
...42、例外:
java允许我们声明抛出一个并没有发生的例外,可将其作为一个“占位符”来理解。
A、java提供了一个名为Throwable的类,所有的例外都必须是它或它子类的实例。
Throwable有两个子类:
Error和E*ception,其中Error代表编译期和系统错误,我们一般不用特意捕获它们。
E*ception是可以从任何标准Java库的类方法中招聘的基本例外类,它们亦可以从我们自己的方法或者在运行期偶发事件中抛出。
java定义的例外类都是E*ception的子类。
-
B、catch的括号内定义的对象名必须是try块中可能抛出的例外类的同一个类或父类、甚至祖先类。
因此说用catch(E*ceptione)能捕获所有例外就不奇怪了。
C、异常的继承结构:
基类为Throwable,Error和E*ception继承Throwable,RuntimeE*ception和IOE*ception等继承E*ception,具体的RuntimeE*ception继承RuntimeE*ception。
D、Error和RuntimeE*ception及其子类成为未检查异常....(unchecked),其它异常成为已检查异常(checked)
E、例外在继承关系中的特殊性:
子类方法只能抛出被父类方法所能抛出的例外所属的例外类或它的衍生类,如果父类方法未定义成抛出例外,则子类覆盖方法也不能抛出例外,如果父类方法声明抛出例外,子类方法可以不声明抛出例外。
但是,父类的构造函数如果声明抛出例外,则子类的构造函数也必须声明抛出,子类也可以抛出根本不存在的例外。
43、RuntimeE*ception介绍
1)、NullPointerE*ception(值为空):
见的最多了,其实很简单,一般都是在null对象上调用方法了。
Strings=null;
booleaneq=s.equals(");//NullPointerE*ception
这里你看的非常明白了,为什么一到程序中就晕呢.
publicintgetNumber(Stringstr){
if(str.equals("A"))return1;
elseif(str.equals("B"))return2;
}
这个方法就有可能抛出NullPointerE*ception,我建议你主动抛出异常,因为代码一多,你可能又晕了。
publicintgetNumber(Stringstr){
if(str==null)
{thrownewNullPointerE*ception("参数不能为空");}
//你是否觉得明白多了
if(str.equals("A"))return1;
elseif(str.equals("B"))return2;
}
2)、NumberFormatE*ception:
继承IllegalArgumentE*ception,字符串转换为数字时出现。
比如inti=Integer.parseInt("ab3");
3)、ArrayInde*OutOfBoundsE*ception:
数组越界。
比如int[]a=newint[3];intb=a[3];
4)、StringInde*OutOfBoundsE*ception:
字符串越界。
比如Strings="hello";charc=s.chatAt(6);
5)、ClassCastE*ception:
类型转换错误。
比如Objectobj=newObject();Strings=(String)obj;
6)、UnsupportedOperationE*ception:
该操作不被支持。
如果我们希望不支持这个方法,可以抛出这个异常。
既然不支持还要这个干吗.有可能子类中不想支持父类中有的方法,可以直接抛出这个异常。
7)、ArithmeticE*ception:
算术错误,典型的就是0作为除数的时候。
8)、IllegalArgumentE*ception:
非法参数,在把字符串转换成数字的时候经常出现的一个异常,我们可以在自己的程序中好好利用这个异常。
44、Java基本类库介绍:
∙Class类:
它是一个特殊的类,它的对象将伴随每个类,当一个类*被编译后,就有一个特殊的对象(class对象)产生,它隐藏在*.class文件中,Class对象是由编译系统自动生成的。