赞
踩
Java三大特性:
封装、继承、多态。
面向对象的四大特征:
封装、继承、多态、抽象。
面向对象7大设计原则:
让每个类只专心处理自己的方法。
软件中的对象(类,模块,函数等)应该对于扩展是开放的,但是对于修改是关闭的。
子类可以去扩展父类,但是不能改变父类原有的功能。
应该通过调用接口或抽象类(比较高层),而不是调用实现类(细节)。
把接口分成满足依赖关系的最小接口,实现类中不能有不需要的方法。
高内聚,低耦合。
面向对象的23种设计模式:
常见的有 抽象工厂模式、工厂方法模式、建造者模式、单例模式。
String不是基本类型。
双等号(==),比较的是他们的值。基本数据类型没有equals方法。
拆箱和装箱:
//自动装箱
Integer total = 99;
//自定拆箱
int totalprim = total;
Integer i = 400;
Integer j = 400;
System.out.println(i==j); //false
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
如果值的范围在-128到127之间,它就从高速缓存返回实例。否则 new 一个Integer对象。new Integer 就是一个装箱的过程了,装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。
Integer和int 的区别:
int是java的原始数据类型,Integer是java为int提供的封类。
Integer的默认值是null;int的默认值是0。
总结:
public:所有地方的类都可以访问。
private:只能在当前类中进行访问。
protected:可以在当前类、当前包、子类中进行访问
不写默认为default:可以在当前类,当前包中进行访问。
==比较的是两个引用在内存中指向的是不是同一对象(即同一内存空间)
equals用来比较 两个对象的内容(值)是否相等。
基本数据类型==比较都是值。
有没有可能两个不相等的对象有相同的hashcode?
有可能。称为hash冲突。
总结
(1) 同一对象上多次调用hashCode()方法,总是返回相同的整型值。
(2) 如果a.equals(b),则一定有a.hashCode() 一定等于 b.hashCode()
(3)如果!a.equals(b),则a.hashCode() 不一定等于 b.hashCode()。此时如果a.hashCode() 总是不等于 b.hashCode(),会提高hashtables的性能。
(4)a.hashCode()==b.hashCode() 则 a.equals(b)可真可假。
(5)a.hashCode()!= b.hashCode() 则 a.equals(b)一定为假。
方法的重载和重写都是实现多态的方式,区别在于:
重载实现的是编译时的多态性。
重写实现的是运行时的多态性。
抽象类特点:
抽象类是抽象的,不是具体的,所以抽象类不能被实例化。但是它仍然具有类的功能,成员变量、成员方法和构造方法的访问方式和普通类一样,也可以实现接口、继承类。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。所以,类的声明、方法体 就不能使用final
去修饰,final表示不可继承和修改,但是变量可以使用final修饰。
抽象类可以有非抽象方法。
抽象类中的抽象方法的访问类型可以是public,protected和默认类型。
public abstract class Employee extends Person implements People{ { public final String a ="1"; static { System.out.println("我是抽象类的static代码块"); } public static void test(){ System.out.println("我是抽象类的static方法"); } public abstract void abstrartMethod(); public void abstrartMethod2() { System.out.println("抽象类也可以拥有非抽象方法"); } }
接口的特点:
public abstract
(只能是这两个关键字,或其中一个或都省略)。因为要被继承,所以是public的。public static final
(只能是这三个关键字,或其中两个/一个或都省略)。接口中有成员变量意义不大,实现类可以通过 接口名称.变量名称
来调用。public interface People {
public static String a ="1";
public static final String b ="2";
public static void test(){
System.out.println("我是接口的静态方法");
}
//普通方法
default void testA2() {
System.out.println("A");
}
public void test1();
}
&是位运算符,表示按位 与运算。(两个操作数中位都为1,结果才为1,否则结果为0)
&&是逻辑运算符,表示逻辑与(and)。
在JDK 1.7之前,switch只能支持byte,short,char,int或者其对应的包装类以及Enum类型.从JDK 1.7之后switch开始支持String类型.但到目前为止,switch都不支持long类型。
还有break的坑:
只要没有break ,就一直往下渗透,包括default。
public class SwitchCaseTest { public static void main(String[] args) { int num = 2; switch (num) { case 1: num++; case 2: num++; case 3: num++; default: num++; break; } System.out.println(num); //5 } }
可变性
简单的来说:String 类中使用 final 关键字字符数组保存字符串, private final char value[]
,所以 String
对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder
中也是使用字符数组保存字符串char[] value
但是没有用 final 关键字修饰,所以这两种对象都是可变的。
安全性
String 是一个字符串常量,final修饰,当创建之后即不能更改,不可被继承,线程安全
StringBuilder 用了synchronized
修饰,线程安全,StringBuffer 线程不安全
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
效率
StringBuffer很多方法都加了 synchronized , 也就是同时刻只能有一个线程去执行一个方法 ,效率就低。
对于三者使用的总结:
留个题目:
public class Test {
public static void main(String[] args) {
StringBuffer a = new StringBuffer("A");
StringBuffer b = new StringBuffer("B");
operator(a, b);
System.out.println(a + "," + b);
}
public static void operator(StringBuffer x, StringBuffer y) {
x.append(y); y = x;
}
}
输出是 AB,B
Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。
四舍五入的原理是在参数上加0.5然后进行下取整。
String s = new String("xyz");
可能创建两个对象也可能创建一个对象。如果常量池中有hello
字符串常量的话,则仅仅在堆中创建一个对象。如果常量池中没有hello
对象,则堆上和常量池都需要创建。
String s = "xyz"
这样创建的对象,JVM会直接检查字符串常量池是否已有"hello"字符串对象,如没有,就分配一个内存存放"hello",如有了,则直接将字符串常量池中的地址返回给栈。(没有new,没有堆的操作)
一个String的经典题目:
String test="javaandpython";
String str1="java";
String str2="and";
String str3="python";
System. out. println(test=="java"+"and"+"python"); //true
System. out. println(test ==str1 + str2 + str3); //false
这是因为字符串字面量拼接操作是在Java编译器编译期间就执行了,也就是说编译器编译时,直接把"java"、“and"和"python"这三个字面量进行”+“操作得到一个"javaandpython” 常量,并且直接将这个常量放入字符串池中,这样做实际上是一种优化,将3个字面量合成一个,避免了创建多余的字符串对象(只有一个对象"javaandpython",在字符串常量池中)。
而字符串引用的"+"运算是在Java运行期间执行的,即str1 + str2 + str3在程序执行期间才会进行计算,它会在堆内存中重新创建一个拼接后的字符串对象。且在字符串常量池中也会有str1,str2与str3,这里创建多少个新的对象与原来字符串常量池中有没有str1、str2、str3有关,如果之前存在就不会创建新的对象。
String str=new String("tarena");
String str2=new String("tarena");
System. out. println(str==str2); //false
这是因为str和str2是在堆中的两个不同地址,最后都指向了常量池的 “tarena”
Throwable 分为Exception(异常) 和 Error(错误) ,二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Error(错误): 是程序无法处理的错误。
Exception(异常): 是程序本身可以处理的异常。常见的有RuntimeException、NullPointerException、ArrayIndexOutOfBoundsException (下标越界异常)。
Java 的所有异常可以分为受检异常(checked exception)和非受检异常(unchecked exception)。
受检异常(checked exception):
编译时必须需要处理的异常,否则编译不通过,除 RuntimeException 及其子类外,其他的 Exception 异常都属于受检异常。比如 调用 sleep()方法
处理的方法为 使用try-catch捕获或者 用 throws 关键字抛出。
非受检异常(unchecked exception):
当程序中出现此类异常时,即使我们没有try-catch捕获它,也没有使用throws抛出该异常,编译也会正常通过。**该类异常包括运行时异常(RuntimeException极其子类)和错误(Error)。**比如 1/0;
位置不同:
throws 用在函数上,后面跟的是异常类,可以跟多个;而 throw 用在函数内,后面跟的
是异常对象。
功能不同:
throws 用来声明异常,让调用者只知道该功能可能出现的问题,可以给出预先的处理方
式;throw抛出具体的问题对象,执行到throw,功能就已经结束了,跳转到调用者,并
将具体的问题对象抛给调用者。也就是说 throw 语句独立存在时,下面不要定义其他语
句,因为执行不到。
throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw 则是抛出了异常,
执行 throw 则一定抛出了某种异常对象。
两者都是消极处理异常的方式,只是抛出或者可能抛出异常,但是不会由函数去处理异
常,真正的处理异常由函数的上层调用处理
字节输入流:InputStream, (读取原始数据)
字节输出流:OutputStream(读取原始数据)
字符输入流:Reader
字符输出流:Writer
1,字节流:以 8 位(即 1 byte,8 bit)作为一个数据单元,数据流中最小的数据单元是字节。
2,字符流:以 16 位(即 1 char,2 byte,16 bit)作为一个数据单元,数据流中最小的数据单元是字符, Java 中的字符是 Unicode 编码,一个字符占用两个字节。
字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。
· 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
· 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
结论:只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
构造器Constructor不能被继承,所以不能被重写。
但是可以重载,因为一个类可以不止一个构造函数,如果没有声明构造函数,会默认生成一个无参的构造函数。
getClass() //返回此 Object 的运行类。
hashCode() //用于获取对象的哈希值。
equals(Object obj) //用于确认两个对象是否“相同”。
clone() //创建并返回此对象的一个副本。
toString() //返回该对象的字符串表示。
notify() //唤醒在此对象监视器上等待的单个线程。
notifyAll() //唤醒在此对象监视器上等待的所有线程。
wait(long timeout) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或 者超过指定的时间量前,导致当前线程等待。
wait(long timeout, int nanos) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
wait() //用于让当前线程失去操作权限,当前线程进入等待序列
finalize() //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
1、lambda表达式
2、接口的默认方法,default方法
3、Comparator 接口
4、Stream 接口
5、Filter 过滤
6、Sort 排序
7、Date API,包含了一组全新的时间日期API
不正确。Java中浮点数默认是double 的。
可以这样声明float类型:
float num = 1.2f;
或者类型转换:
float num = (float) 1.2
这是两个不同的概念。
注释:
对代码的解释,方便别人阅读你的代码
注释分为:
注解:
注解 ,参与代码编译,以@开头的,与工具一起使用。对于位置、语法、内容有一定的限制。注释 ,可以随意在任务位置填写内容,对代码任何没有影响。
例如 @SuppressWarnings(value=”unchecked”)
this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。
super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。
其他:
demo:
class Student { private int id; String name; protected boolean sex ; pub1ic f1oat score; } pub1ic class Get { //获取反射机制三种方式 public static void main(String[] args) throws ClassNotFoundException { //方式一(通过建立对象) Student stu = new StudentO ; Class classobj1 = stu. getClassO; System. out. print1n(classobj1. getNameO); //方式二(所在通过路径-相对路径) Class classobj2 = Class . forName (" fanshe . Student") ; System. out. println(classobj2. getName0) ; //方式三(通过类名) Class classobj3 = Student.class; System. out. println(classobj3. getName0) ; } }
引用类型 | 被垃圾回收时间 | 用途 | 生存时间 |
---|---|---|---|
强引用 | 从来不会 | 对象的一般状态 | JVM停止运行时终止 |
软引用 | 当内存不足时 | 对象缓存 | 内存不足时终止 |
弱引用 | 正常垃圾回收时 | 对象缓存 | 垃圾回收后终止 |
虚引用 | 正常垃圾回收时 | 跟踪对象的垃圾回收 | 垃圾回收后终止 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。