面向对象

  1. 继承:继承是从已有的类中得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类,基类);得到继承信息的类被称为子类(派生类)。继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段。
  2. 封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只是向外界提供最简单的编程接口。
  3. 多态性:多态性是指允许不同子类类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供服务的方式,但一切对A系统来说都是透明的。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称后绑定)。运行时的多态时面向对象最精髓的东西,要实现多态需要做两件事:1.方法重写(子类继承父类并重写父类中已有的或抽象的方法);2.对象造型(用父类型的引用引用子类型对象,这样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。
  4. 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。

访问权限修饰符:

修饰符当前类同包子类其它包
public
protected×
default××
private×××

Java语法

如何理解clone对象

  • 为什么要用clone ?
    在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在Java语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但实现clone() 方法是其中最简单,也是最高效的手段。

  • new一个对象的过程和clone一个对象的过程区别
    new操作符的本意是分配内存。程序执行到new操作符时,首先去看new操作符后面的类型,因为知道了类型,才知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他引用发布到外部,在外部就可以使用这个引用操作这个对象。clone在第一步是和new相似的,都是分配内存,调用clone方法时,分配的内存和元对象(即调用clone方法的对象)相同,然后再使用元对象中对应的各个域,填充新对象的域,填充完毕后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。(属于浅拷贝)

  • 浅拷贝和深拷贝

  • 浅拷贝:只是将源对象中的“引用(在栈内存中)”复制到新的对象中,而在堆内存中的数据没有被复制,当改变源对象中的数据时,新对象中也会发生对应的变化

  • 深拷贝:将按照源对象中的数据内容复制并创建对象,其引用会发生变化,接着将“复制”对象的“引用”复制到新的对象中,当改变源对象的数据时,在新对象中的数据不会发生变化。

& 和 && 的区别

  1. &运算符有两种用法:(1)按位与;(2)逻辑与;
  2. &&运算是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者要求运算符作于两端的布尔值都是true整个表达式的值才是true。
  3. &&之所以被称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是null而不是空字符串,应该写为username != null && !username.equals(""),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则产生NUllPointerException 异常。

逻辑或运算符(|)和短路或运算符(||)的差别也是如此。

在条件语句中如何跳出当前的多重嵌套循环

  • 在最外层的循环上加上break;结束当前循环。
  • 如果在最外层加上continue;则表示跳出当前循环,直接进行下一循环;

两个对象值相同,不会有不同的hashcode

Java对于equals方法和hashCode方法是这样规定的:

  1. 如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
  2. 如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大降低(对于使用哈希存储系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。

实现高质量的equals方法的诀窍包括

  • 使用==操作符检查“参数是否为这个对象的引用”;
  • 使用instanceof操作符检查“参数是否为正确类型”;
  • 对于类中的关键属性,检查参数传入对象的属性是否与之相匹配;
  • 编写完equals方法后,问自己它是否满足对称性、传递性、一致性;
  • 重写equals时总是要重写hashCode;
  • 不要将equals方法参数中的Object对象替换为其它类型,在重写时不要忘记@Override注解。
  • == 是属于运算符,只能比较基本数据类型
    equals属于方法不能用于基本数据类型,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址。

String类是final类,不可以被继承

  • 继承String本身就是一个错误行为,对String类型最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)而不是继承关系(Is-A);

当一个对象被当作参数传递到一个方法后,此方法可以可以改变这个兑现的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

  • 是值传递。Java语言的方法第哦啊用只支持参数传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对象引用的改变是不会影响到调用者的。

重载和重写的区别

  • 方法的重载和重写都是实现多态的方式,区别在与前者实现的是编译时的多态性,而后者实现的时运行时的多态性。

  • 重载发生在一个类中,同名的方法如果有不同的参数列表(参数个数不同或者二者都不同)则视为重载;

  • 重写发生在子类与父类直间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。

  • 方法重载规则:
    1. 方法名一致,参数列表中参数顺序,类型,个数不同。
    2. 重载与方法的返回值无关,存在于父类和子类,同类中。
    3. 可以抛出不同的异常,可以有不同修饰符。

  • 方法重写规则:
    1. 参数列表必须完全于被重写方法的一致,返回类型必须完全与被重写方法返回类型一致。
    2. 构造方法不能被重写,声明为final的方法不能被重写,声明为static的方法不能被重写,但是能够被再次声明。
    3. 访问权限不能比父类中被重写的方法的访问权限更低。
    4. 重写方法能够抛出任何非强制异常(UncheckedException,也叫非运行时异常),无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

char型变量中能不能存储一个中文汉字

  • char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符集中的编号,这是同意的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。

使用Unicode意味着字符在jvm内部和外部有不同的表现形式,在jvm内部都是Unicode,当这个字符被从JVM内部转移到外部时(例如存入文件系统中),需要进行编码转换。所以Java中有字节流和字符流,以及在字符流和字节流质检进行转换的转换流,如InputStreamReader和OutputStreamReader,这两个类时字节流和字符流之间的适配器类,承担了编码转换的任务;

抽象类和接口有什么异同
不同:

  • 抽象类:
    1. 抽象中可以定义构造器
    2. 可以有抽象方法和具体方法
    3. 抽象类中可以定义
    4. 有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法
    5. 抽象类中可以包含静态方法
    6. 一个类只能继承一个抽象类
    7. 抽象类中成员可以是private,默认,protected、public

  • 接口:
    1. 接口中不能定义构造器
    2. 方法全部都是抽象方法
    3. 接口中的成员都是public
    4. 接口定义的成员变量实际上都是常量
    5. 接口中不能有静态方法
    6. 一个类可以实现多个接口

相同:

  • 不能够实例化
  • 可以将抽象类和接口类型作为引用类型
  • 一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部实现,否则该类仍然需要被声明为抽象类

抽象方法是否可同时是静态,是否可同时是本地方法(native),是否可同时被synchronized ???

  • 都不能。
  1. 抽象方法需要子类重写,而静态方法是无法被重写的,因此二者是矛盾的。
  2. 本地方法是由本地代码实现的方法,而抽象方法是没有实现的,也是矛盾的。
  3. synchronized 和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。

静态变量和实例变量的区别

  • 静态变量:是被static修饰的变量,也称类变量,它属于类,部署类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;
  • 实例变量:必须依存于某一实例,需要创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。

Java中的多态

Java中实现多态的机制是什么?
靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

Java的异常处理

Java中异常分类

  • 按照异常需要处理的时机分为编译时异常(也叫强制性异常)也叫CheckedException 和运行时异常(也叫非强制性异常)也叫RuntimeException.只有Java语言提供了Checked异常,Java认为Checked异常都是可以被处理的异常,所以Java程序必须显示处理Checked异常。如果程序没有处理Checked异常,该程序在编译时就会发生错误无法编译。这体现了Java的设计哲学:没有完善错误处理的代码根本没有机会被执行。
  • 对Checked异常处理方法有两种:
    1. 当方法知道如何处理该异常,则用try…catch块来处理该异常。
    2. 当前方法不知道如何处理,则在定义方法是声明抛出该异常。

error和exception的区别

  • Error类和Exception类的父类都是Throwable类,他们的区别如下。
    1. Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法第哦啊用栈溢出等。 对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这种错误,建议程序终止。
    2. Exception 类表示程序可以处理异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不是应该随意终止异常。
    3. Exception 类又分为运行时异常和受检查的异常,运行时异常,编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。而受检查的异常,要么用try…catch捕获,要么用throws字句声明抛出,交给它的父类处理,否则编译不过去。

Java异常处理机制

  • Java对异常进行了分类,不同类型的异常分别用不同的Java表示,所有异常的根类为 java.lang.Throwable,Throwable下面又派生了两个子类:error和exception,error表示应用程序本身无法克服和恢复的一种严重问题;
  • exception 表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉。
  • Java为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try…catch处理或用throws声明继续抛给上层调用方法处理,所以普通异常也成为checked异常,而系统异常可以处理也可以不处理,所编译器不强制用try…catch处理或用throws声明,所以系统异常称为unchecked异常。

常见的运行时异常情况

  1. java.lang.NullPointerException 空指针异常;出现原因:调用了未经初始化的对象或者是不存在的对象。
  2. java.lang.ClassNotFoundException 指定的类找不到;出现原因:类的名称和路径加载错误;通常都是程序试图通过字符串来加载某个类时可能引发异常。
  3. java.lang.NumberFomatException 字符串转为数字异常;出现原因:字符型数据中包含非数字型字符
  4. java.lang.IndexOutOfBoundsException 数组角标越界异常,常见于操作数组对象时发生。
  5. java.lang.IllegalArgumentException 方法传递参数错误
  6. java.lang.ClassCastException 数据类型转换异常。
  7. java.lang.NoClassDefFoundException 未找到类定义错误
  8. SQLException SQL 异常,常见于操作数据库时SQL语句错误。
  9. java.lang.InstantiationException 实例化异常
  10. java.lang.NoSuchMethodException 方法不存在异常。

throw和throws的区别

  • throw:
    1. throw语句用在方法体内,表示抛出异常,由方法体内的语句处理。
    2. throw是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行throw一定是抛出了某种异常。

  • throws:
    1. throws语句是用在方法声明后面,表示如果抛出异常,由该方法的调用者进行异常处理。
    2. throws主要声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常类型。
    3. throws表示出现异常的一种可能性,并不一定会发生这种异常。

final、 finally、fialize

  1. final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,被其修饰的类不可继承。
  2. finally:异常处理语句结构的一部分,表示总是执行
  3. finalize:Object类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其它资源回收,例如关闭文件等。该方法更像是一个对象生命周期的临终方法,当该方法被系统调用则代表该对象即将‘死亡’,但是需要注意的是。我们主动行为上去调用该方法并不会导致该对象死亡,这是一个被动的方法(回调方法),不需要我们调用。

JavaSE常用API

  • Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11.四舍五入的原理是在参数上加0.5然后进行取整
  • Java5以前switch(expr)中,expr只能是 byte、short、int、char.从Java5开始,Java中引入了枚举类型。expr也可以是enum类型。从Java7开始,expr还可以是字符串,但是长整型在目前所有版本中都是不可以的。
持续更新中。。。。。。