1、简单易学、有丰富的类库
2、面向对象(Java最重要的特性,让程序耦合度更低,内聚性更高)基本类型
3、与平台无关性(JVM是Java跨平台使用的根本)
4、可靠安全
5、支持多线程 (可以问一下是否了解多线程, 线程的创建方式有哪些?)
什么是封装
什么是继承
什么是多态
在项目中的实际应用有哪些?
面向过程:是分析解决问题的步骤,然后用函数把这些步骤一步一步地实现,然后在使用的时候一
一调用则可。性能较高,所以单片机、嵌入式开发等一般采用面向过程开发
面向对象:是把构成问题的事务分解成各个对象,而建立对象的目的也不是为了完成一个个步骤,
而是为了描述某个事物在解决整个问题的过程中所发生的行为。面向对象有封装、继承、多态的特
性,所以易维护、易复用、易扩展。可以设计出低耦合的系统。 但是性能上来说,比面向过程要
低
**装箱就是自动将基本数据类型转换为包装器类型(int–>Integer);调用方法:**Integer的
valueOf(int) 方法
**拆箱就是自动将包装器类型转换为基本数据类型(Integer–>int)。调用方法:**Integer的
intValue方法
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}
true
false
重写就是 重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子
类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,
参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对
方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。
重写总结: 1.发生在父类与子类之间 2.方法名,参数列表,返回类型(除过子类中方法的返回类型
是父类中返回类型的子类)必须相同 3.访问修饰符的限制一定要大于被重写方法的访问修饰符
(public>protected>default>private) 4.重写方法一定不能抛出新的检查异常或者比被重写方法申
明更加宽泛的检查型异常
在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不
同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是
否相同来判断重载。
重载 总结: 1.重载Overload是一个类中多态性的一种表现 2.重载要求同名方法的参数列表不同(参
数类型,参数个数甚至是参数顺序) 3.重载的时候,返回值类型可以相同也可以不相同。无法以返回
型别作为重载函数的区分标准
== 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是
否是指相同一个对象。比较的是真正意义上的指针操作。
1、比较的是操作符两端的操作数是否是同一个对象。 2、两边的操作数必须是同一类型的(可以是
父子类之间)才能编译通过。 3、比较的是地址,如果是具体的阿拉伯数字的比较,值相等则为
true,如: int a=10 与 long b=10L 与 double c=10.0都是相同的(为true),因为他们都指向地
址为10的堆。
equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所
以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object
中的equals方法返回的却是==的判断。
总结:
所有比较是否相等时,都是用equals 并且在对常量相比较时,把常量写在前面,因为使用object的
equals object可能为null 则空指针
在阿里的代码规范中只使用equals ,阿里插件默认会识别,并可以快速修改,推荐安装阿里插件来
排查老代码使用“==”,替换成equals
说一下其中的equals和hash方法
为什么要重写这两个方法
String是只读字符串,它并不是基本数据类型,而是一个对象。从底层源码来看是一个final类型的
字符数组,所引用的字符串不能被改变,一经定义,无法再增删改。每次对String的操作都会生成
新的String对象。
private final char value[];
每次+操作 : 隐式在堆上new了一个跟原字符串相同的StringBuilder对象,再调用append方法 拼
接+后面的字符。
StringBuffer和StringBuilder他们两都继承了AbstractStringBuilder抽象类,从
AbstractStringBuilder抽象类中我们可以看到他们的底层都是可变的字符数组,所以在进行频繁的字符串操作时,建议使用StringBuffer和
StringBuilder来进行操作。 另外StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
强引用是平常中使用最多的引用,强引用在程序内存不足(OOM)的时候也不会被回收
String str = new String("str");
System.out.println(str);
弱引用就是只要JVM垃圾回收器发现了它,就会将之回收
WeakReference<String> wrf = new WeakReference<String>(str);
可用场景: Java源码中的 java.util.WeakHashMap 中的 key 就是使用弱引用,一旦我不需要某个引用,JVM会自动帮我处理它,这样我就不需要做其它操作
软引用在程序内存不足时,会被回收
// 注意:wrf这个引用也是强引用,它是指向SoftReference这个对象的,
// 这里的软引用指的是指向new String("str")的引用,也就是SoftReference类中T
SoftReference<String> wrf = new SoftReference<String>(new String("str"));
可用场景: 创建缓存的时候,创建的对象放进缓存中,当内存不足时,JVM就会回收早先创建的对象。
虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。注意哦,其它引用是被JVM回收后才被传入 ReferenceQueue 中的。由于这个机制,所以虚引用大多被用于引用销毁前的处理工作。还有就是,虚引用创建的时候,必须带有 ReferenceQueue
PhantomReference<String> prf = new PhantomReference<String>(new String("str"),
new ReferenceQueue<>());
可用场景: 对象销毁前的一些操作,比如说资源释放等。 Object.finalize() 虽然也可以做这类动作,但是这个方式即不安全又低效
泛型是Java SE 1.5之后的特性, 《Java 核心技术》中对泛型的定义是:
“泛型” 意味着编写的代码可以被不同类型的对象所重用。
“泛型”,顾名思义,“泛指的类型”。我们提供了泛指的概念,但具体执行的时候却可以有具体的规则
来约束,比如我们用的非常多的ArrayList就是个泛型类,ArrayList作为集合可以存放各种元素,如
Integer, String,自定义的各种类型等,但在我们使用的时候通过具体的规则来约束,如我们可以约
束集合中只存放Integer类型的元素,如
使用泛型的好处?
以集合来举例,使用泛型的好处是我们不必因为添加元素类型的不同而定义不同类型的集合,如整
型集合类,浮点型集合类,字符串集合类,我们可以定义一个集合来存放整型、浮点型,字符串型
数据,而这并不是最重要的,因为我们只要把底层存储设置了Object即可,添加的数据全部都可向
上转型为Object。 更重要的是我们可以通过规则按照自己的想法控制存储的数据类型。
拉链法:每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表进行存储.
开放定址法:一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入
List iniData = new ArrayList<>()再哈希:又叫双哈希法,有多个不同的Hash函数.当发生冲突时,使用第二个,第三个….等哈希函数
计算地址,直到无冲突.
浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指
向原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象.
深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向
被复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的
对象都复制了一遍.
静态变量和静态方法、静态代码块、静态内部类
执行,并且finally的执行先于try中的
不管有没有出现异常,finally中的代码都会执行
当try和catch都有return时,finally仍然会执行
finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的
值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数
返回值是在finally执行前确定的;
finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
序列化是一种将对象转换为字节流的过程,以便可以将对象保存到磁盘上,将其传输到网络上,或者将其存储在内存中,以后再进行反序列化,将字节流重新转换为对象。
序列化在 Java 中是通过 java.io.Serializable 接口来实现的,该接口没有任何方法,只是一个标记接口,用于标识类可以被序列化。
当你序列化对象时,你把它包装成一个特殊文件,可以保存、传输或存储。反序列化则是打开这个文件,读取序列化的数据,然后将其还原为对象,以便在程序中使用。
序列化是一种用于保存、传输和还原对象的方法,它使得对象可以在不同的计算机之间移动和共享,这对于分布式系统、数据存储和跨平台通信非常有用。
transient进行修饰
Java中的IO流
InputStream/Reader: 所有输入流的基类,前者是字节输入流,后者是字符输入流
OutPutStream/Writer: 所有输出流的基类,前者是字节输入流,后者是字符输入流
定义:反射机制是在运行时,对于任意一个类,都能知道这个类所有的属性和方法;对于任意一个对象,都能够调用它的任意一个方法。在Java中,只要给定类的名字,就可以通过反射机制获得类的所有信息。
这种动态获取的信息以及动态调用对象的方法称为Java语言的反射机制
反射的应用
Class.forName('com.mysql.jdbc.Driver.class');//加载MySQL的驱动类
反射实现的方式:
获取Class对象
实现Java反射的类
反射机制的优缺点