Java有什么特点?
1.面向对象(封装,继承,多态)
2.平台无关性(JVM实现的平台无关性)
3.GC垃圾回收机制
4.异常处理机制
5.支持多线程
6.支持网络编程
面向对象和面向过程的区别
* 面向过程:把问题分解为一个个的步骤,再用代码把这些步骤依次实现,性能较高。
比如单片机,嵌入式开发,Linux/Unix等一般采用面向过程开发。
* 面向对象:容易维护,复用,扩展。类调用需要实例化,开销大。性能低于面向过程。
因为有封装,继承,多态的特性,可以设计出低耦合的系统,使系统更加灵活,更加容易维护。
Java和C++的区别
* 都是面向对象的语言,支持封装,继承,多态
* Java用引用代替指针,不能直接访问内存,更安全
* Java的类是单继承的,而C++支持多重继承。Java的接口可以多继承
* Java有自动内存管理机制,不需要程序员手动释放内存
Java基本数据类型
* Java有8种基本数据类型
byte:1字节
short:2字节
int:4字节
long:8字节
char:2字节
float:4字节
double:8字节
boolean:1字节
基本类型和引用类型的区别
* 除了基本数据类型,其他全都是引用数据类型,包括数组,集合,基本数据类型的包装类等等
* 区别:
1.赋值方法不同:基本类型直接赋值,应用类型通过new创建对象,再为对象的属性进行赋值
2.比较方法不同:对于==来说,引用类型比较引用地址,基本类型比较值
3.参数传递不同:基本类型传递是值传递,引用数据类型是引用传递(地址传递)
4.存储位置不同:基本类型直接存储在JVM的栈上,引用数据类型被创建时,先在栈上分配一块地址存储引用,
对象的具体信息都存储在堆内存上,由栈中的引用指向堆中对象的地址
引用类型如何创建?
例如:Person p = new Person(20);
1.首先在栈内存中为p分配一块空间
2.然后在堆内存中为Person对象分配一块空间,并为其赋初值0
3.根据Person对象的定义,调用构造方法,为其属性赋值20
4.将Person对象在堆内存的地址,赋值给栈内存中的p,可以通过p来找到堆中对象的具体信息
重载和重写的区别
* 重载:发生在同一个类中,方法名必须相同,参数类型不同,个数不同,顺序不同,返回值和访问修饰符可以不同
* 重写:发生在子类中,是子类对于父类允许访问范围内的方法的实现过程的重新编写。方法名,参数列表必须相同
返回值,异常小等于父类,访问修饰符的范围大于等于父类。
总而言之:方法提供的行为改变,而方法的外表并没有改变
面向对象三大特性
* 封装
把描述一个对象的属性和行为的代码封装在一个类中,属性用变量定义,行为用方法定义
方法可以直接访问同一个对象中的属性
* 继承
子类继承父类的特征和行为,子类可以拥有父类非私有的方法和属性
同时,子类可以对父类进行扩展,也可以重写父类的方法,但会提高代码之间的耦合性
* 多态
编译时多态:主要指方法的重载
运行时多态:指程序中定义的对象引用所指向的类型在运行期间才能确定
运行时多态有三个条件:继承,重写,向上转型
向上转型,向下转型
向上转型:用子类对象来实例化父类对象,可以实现多态
向下转型:用父类对象来实例化子类对象,可以调用子类扩展的方法
final关键字的作用
* final修饰的类叫最终类,不能被继承
* final修饰的方法不能被重写
* final修饰的变量不能被修改
1.基本变量被修饰则数值不能修改
2.引用变量被修饰则不能指向别的对象,但被引用对象的数值可以修改
final、finally、finalize区别
* final可以修饰类,变量,方法
修饰类表示该类不能被继承,修饰方法表示该方法不能被重写,修饰变量则表示值不能修改
* finally:一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,
表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码
* finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,
当我们调用System的gc()方法的时候,由垃圾回收器调用finalize(),回收垃圾。
hashCode()和equals()
* hashCode()和equals()的作用其实一样,都是用来比较两个对象是否相等一致
* hashCode()注重性能,equals()注重可靠性
1.hashCode()和equals()区别
* 既然equals()可靠性强为什么还要hashCode()?
重写的equals()中比较手段比较全面而复杂,效率较低。
用hashCode()来比较,只需要生成一个hash值就可以了,效率较高
* 既然hashCode()效率高为什么还要用equals()?
因为hashCode()并不是完全可靠,有时候由于公式的问题,不同对象生成的hashCode也会一样,无法保证绝对可靠
equals()相等的两个对象,他们的hashCode肯定相等,也就是说equals()绝对可靠
hashCode()相等的两个对象,他们的equals()不一定相等,也就是说hashCode()不是绝对可靠的
2.注意事项
1.每次对比,先比较hashCode,如果不相等,则两个对象肯定不同,不需要再用equals了
如果hashCode相等,再比较equals(),保证了效率和可靠性
2.hashCode()只有在hash容器中才需要重写,如HashSet,HashMap,HashTable等等。
由于哈希集合中要求能存放不同类型的对象,所以必须避免hashCode相同,但对象不同的情况,必须两个方法都重写
3.如果不重写的话,hashCode()和equals()都是属于Object类的方法,hashCode()由内存地址生成哈希值,
而equals()对于引用类型变量来说是比较引用地址,所以在很多情况下需要重写这两个方法。
4.String类型重写了hashCode()和equals(),可以把String对象作为哈希集合(映射)的key使用
接口和抽象类的区别
1.接口方法默认是public,所有方法在接口中不能实现(Java8开始可以有默认实现),抽象类可以有非抽象的方法
2.接口中除了static,final变量,不能有其他变量,抽象类则不一定
3.类可以实现多个接口,但只能实现一个抽象类。接口可以多继承而类不行
4.抽象是对类的抽象,是一种模板设计。而接口是对行为的抽象,是一种行为的规范
Object类有什么常用方法
equals():比较两个对象的引用地址值是否相等,可被子类重写修改比较规则
hashCode():获取哈希码
toString():把数据转换成字符串
getClass():获取类的结构信息
finalize():垃圾回收前执行的方法
clone():克隆对象
wait():多线程等待
notify():唤醒随机一个线程
notifyAll():唤醒所有线程
缓存池
基本类型的valueOf()方法会调用缓存池获取数据
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
判断值是否在缓存池中,如果在直接返回缓存池的内容,不在就新建一个。
编译器在自动装箱的过程中调用valueOf()方法
Integer m = 123;
Integer n = 123;
System.out.println(m == n); // true
字符串常量池
字符串常量池用来保存所有字符串字面量,这些字面量在编译时期就确定了
String的intern()方法会在运行过程中将字符串添加到字符串常量池中,调用该方法时,
如果字符串常量池中已经有这个字符串字面量,则直接返回这个字符串的引用
如果字符串常量池中不存在这个字符串字面量,则创建一个新字符串,并返回这个字符串的引用
问:String s = new String("abc")会创建几个对象
一共创建两个对象(前提是常量池中还没有"abc"字符串对象)
1."abc"属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象,指向"abc"
2.使用new会在堆中创建一个字符串对象
同道中人
我是c++