大家好,又见面了,我是你们的朋友全栈君。
Java是面向对象的编程语言,不同于C语言是面向过程的。对于面向对象和面向过程的区别,举一个简单的例子说明一下(我们以洗衣机洗衣服为例):
method01()
method02()
method03()
method04()
method05()
Person
):Person
在洗衣机洗衣服这个程序任务中有三个作用,分别是打开洗衣机
、放入要洗的衣服
、放入洗衣粉
。Machine
):Machine
在洗衣机洗衣服这个程序任务中有两个作用,分别是清洗
、烘干
。从上面这个例子能看出,面向过程的编程方式比较直接且高效,而面向对象的编程方式更易复用、扩展和维护!
多态的三要素:继承 、重写、父类指向子类引用!
什么是编译形语言,什么又是解释形语言?
那么为什么说Java 是编译型语言呢
第一个观点认为 Java 是编译型语言,因为Java程序想要运行,那么第一步就是要使用Javac进行编译(将Java源文件编译成.class
二进制文件)。没有经过编译的.java
文件,是没办法运行的!
那么为什么又说Java 是解释型语言呢?
那么第二个观点则是认为Java是解释型语言,Java经过编译,Javac 将.java
源文件编译成.class
二进制文件之后,仍然需要借助 JVM 的解释执行。
综合上面两个观点来看,Java似乎既有编译型语言的特点,又有解释型语言的特点,也没有看到哪本权威的书籍上认定Java就是哪一种类型的语言。
如图所示:
8种基本数据类型和取值范围:
基本类型 | 大小(位/bit) | 字节数(byte) | 最小值 | 最大值 | 默认值 | 包装器类型 |
---|---|---|---|---|---|---|
boolean | – | – | false | true | false | Boolean |
char | 16 bits | 2 bytes | Unicode 0 | Unicode 2^16-1 | 空 | Character |
byte | 8 bits | 1 byte | -2^7 | 2^7-1 | 0 | Byte |
short | 16 bits | 2 bytes | -2~15 | 2^15-1 | 0 | Short |
int | 32 bits | 4 bytes | -2^31 | 2^31-1 | 0 | Integer |
long | 64 bits | 8 bytes | -2^63 | 2^63-1 | 0 | Long |
float | 32 bits | 4 bytes | 0.0 | Fload | ||
double | 64 bits | 8 bytes | 0.0 | Double |
注意:对于boolean
值,在Java规范中并没有给出其储存大小,在《Java虚拟机规范》中给出了4个字节,和boolean
数组1个字节的定义,具体还要看虚拟机实现是否按照规范来,所以1个字节、4个字节都是有可能的。除了void之外,其他8种基本数据类型被称为八大基本数据类型。
图中从左向右的转换都是隐式转换,无需再代码中进行强制转换。从右向左均要进行强制类型转换,才能通过编译。强制转换会丢失精度。
二者相同之处
是值传递。java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。
java中只有值传递,基本类型传递的是值的副本,引用类型传递的是引用的副本
直接看一张图就可以理解他们的区别了:
private
,则子类就无法重写了)。List
:有序、可重复集合。按照对象插入的顺寻保存数据,允许多个Null
元素对象,可以使用iterator
迭代器遍历,也可以使用get(int index)
方法获取指定下标元素。Set
:无序、不可重复集合只允许有一个Null
元素对象,取元素时,只能使用iterator
迭代器逐一遍历。Map
: key-value 键值对形式的集合,添加或获取元素时,需要通过key来检索到value。Collecttion 集合体系结构简图:
参考文章:Java集合中List,Set以及Map等集合体系详解
equals()
只是判断对象属性是否相同,hashCode()
要判断二者地址是否相同。java中如果要判断两个对象是否相等,需要同时满足地址 + 属性
都相同!
equals()
比较返回true
),那么它们的 hashCode
值一定要相同;hashCode
相同,它们并不一定相同;举例子:
只重写 equals()
方法,不重写 hashcode()
方法:
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// 省略 get,set方法...
}
执行下面的程序看看效果:
public class hashTest {
@Test
public void test() {
Student stu1 = new Student("Jimmy",24);
Student stu2 = new Student("Jimmy",24);
System.out.println("两位同学是同一个人吗?"+stu1.equals(stu2));
System.out.println("stu1.hashCode() = "+stu1.hashCode());
System.out.println("stu1.hashCode() = "+stu2.hashCode());
}
}
如果重写了 equals()
而未重写 hashcode()
方法,可能就会出现两个没有关系的对象 equals 相同(因为equals都是根据对象的特征进行重写的),但 hashcode 不相同的情况。因为此时 Student
类的 hashcode()
方法就是 Object 默认的 hashcode()
方 法,由于默认的 hashcode()
方法是根据对象的内存地址经哈希算法得来的,所以 stu1 != stu2
,故两者的 hashcode 值不一定相等。
根据 hashcode 的规则,两个对象相等其 hash 值一定要相等,矛盾就这样产生了。上面我们已经解释了为什么要使用 hashcode 算法,所以即使字面量相等,但是产生两个不同的 hashCode 值显然不是我们想要的结果。
如果我们在重写 equals() 时,也重写了 hashCode() 方法:
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// 省略 get,set方法...
}
再来看执行结果:
两位同学是同一个人吗?true
stu1.hashCode() = 71578563
stu1.hashCode() = 71578563
从 Student
类重写后的 hashcode()
方法中可以看出,重写后返回的新的 hash 值与 Student
的两个属性是有关,这样就确保了对象和对象地址之间的关联性。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/126496.html原文链接:https://javaforall.cn