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:可以在当前类,当前包中进行访问。
基本数据类型==比较都是值。
有没有可能两个不相等的对象有相同的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 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
}
}
private final char value[]
,所以 String
对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder
中也是使用字符数组保存字符串char[] value
但是没有用 final 关键字修饰,所以这两种对象都是可变的。
synchronized
修饰,线程安全,StringBuffer 线程不安全
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
对于三者使用的总结:
留个题目:
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;
位置不同:
字节输入流: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等),而字符流只能处理字符类型的数据。
结论:只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。
构造器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停止运行时终止 |
软引用 | 当内存不足时 | 对象缓存 | 内存不足时终止 |
弱引用 | 正常垃圾回收时 | 对象缓存 | 垃圾回收后终止 |
虚引用 | 正常垃圾回收时 | 跟踪对象的垃圾回收 | 垃圾回收后终止 |