本文共 9125 字,大约阅读时间需要 30 分钟。
abstract 表明类或者成员方法具有抽象属性assert 断言,用来进行程序调试boolean 基本数据类型之一,声明布尔类型的关键字break 提前跳出一个块byte 基本数据类型之一,字节类型case 用在switch语句之中,表示其中的一个分支catch 用在异常处理中,用来捕捉异常char 基本数据类型之一,字符类型class 声明一个类const 保留关键字,没有具体含义continue 回到一个块的开始处default 默认,例如,用在switch语句中,表明一个默认的分支。Java8 中也作用于声明接口函数的默认实现do 用在do-while循环结构中double 基本数据类型之一,双精度浮点数类型else 用在条件语句中,表明当条件不成立时的分支enum 枚举extends 表明一个类型是另一个类型的子类型。对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口final 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量finally 用于处理异常情况,用来声明一个基本肯定会被执行到的语句块float 基本数据类型之一,单精度浮点数类型for 一种循环结构的引导词goto 保留关键字,没有具体含义if 条件语句的引导词implements 表明一个类实现了给定的接口import 表明要访问指定的类或包instanceof 用来测试一个对象是否是指定类型的实例对象int 基本数据类型之一,整数类型interface 接口long 基本数据类型之一,长整数类型native 用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的new 用来创建新实例对象package 包private 一种访问控制方式:私用模式protected 一种访问控制方式:保护模式public 一种访问控制方式:共用模式return 从成员方法中返回数据short 基本数据类型之一,短整数类型static 表明具有静态属性strictfp 用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范super 表明当前对象的父类型的引用或者父类型的构造方法switch 分支语句结构的引导词synchronized 表明一段代码需要同步执行this 指向当前实例对象的引用throw 抛出一个异常throws 声明在当前定义的成员方法中所有需要抛出的异常transient 声明不用序列化的成员域try 尝试一个可能抛出异常的程序块void 声明当前成员方法没有返回值volatile 表明两个或者多个变量必须同步地发生变化while 用在循环结构中
解读:final关键字是java的一个修饰符,可以用来声明类,方法,属性。
被final修饰的类,方法,属性,具有以下特点:
1)final修饰类,该类不可被继承2)final修饰方法,该方法不可被重写,可以被继承和重载
3)final修饰属性,该属性为常量,不可改变
现假设有对象A和B,如果A.equals(B)==true,那么对象A和对象B的对象内容相等,hashcode也相同。(hashcode相同对象不一定相同);
equals必须满足3个特性:对称性,自反性,一致性;
在重写equals方法时一定要重写hashcode方法;equals和运算符双等号的区别
1)equals:父类的equals方法是用来比较方法两个对象的地址是否相等,String类的equals方法是用来比较两个字符串的内容是否相同。equals方法不能用于基本数据类型的变量,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址,如果重写了equals,就看equals的具体实现规则2)"==":如果比较的对象是基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,则比较的是对象的地址值是否相等
先来一段代码测试一下:
package com.test;import org.omg.CORBA.PRIVATE_MEMBER;public class Test { public static void main(String[] args) { String s1 = "123"; String s2 = "123"; System.out.println(s1.equals(s2)); System.out.println(s1 == s2); String s3 = new String("456"); String s4 = new String("456"); System.out.println(s3.equals(s4)); System.out.println(s3 == s4); }}输出结果:"C:\Program Files\Java\jdk1.8.0_212\bin\java.exe" "-javaagent:D:\JetBrains\IntelliJ IDEA 2019.3.2\lib\idea_rt.jar=54178:D:\JetBrains\IntelliJ IDEA 2019.3.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_212\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_212\jre\lib\rt.jar;F:\workspace\springtest\target\classes;D:\resp\org\springframework\spring-core\4.3.18.RELEASE\spring-core-4.3.18.RELEASE.jar;D:\resp\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;D:\resp\org\springframework\spring-context\4.3.18.RELEASE\spring-context-4.3.18.RELEASE.jar;D:\resp\org\springframework\spring-aop\4.3.18.RELEASE\spring-aop-4.3.18.RELEASE.jar;D:\resp\org\springframework\spring-beans\4.3.18.RELEASE\spring-beans-4.3.18.RELEASE.jar;D:\resp\org\springframework\spring-expression\4.3.18.RELEASE\spring-expression-4.3.18.RELEASE.jar;D:\resp\org\springframework\spring-jdbc\4.3.18.RELEASE\spring-jdbc-4.3.18.RELEASE.jar;D:\resp\org\springframework\spring-tx\4.3.18.RELEASE\spring-tx-4.3.18.RELEASE.jar" com.test.TesttruetruetruefalseProcess finished with exit code 0
再来看一个例子,关于equals方法重写和不重写比较的差异:
package com.test.main;public enum EnumA { NAME(1,"1"); private int code; private String name; EnumA(int code, String name) { this.code = code; this.name = name; }}package com.test.main;public class Test { public static void main(String[] args) { TestB testB = new TestB(); boolean result = EnumA.NAME.equals(testB.getEnum()); System.out.println(EnumA.NAME.hashCode());//枚举EnumA的hashcode System.out.println(testB.getEnum().hashCode());//TestB的hascode System.out.println(result); //因为Enum默认重写了equals和hashcode方法,内部比较的也是地址,但是枚举类是静态类,对象是放在一个共享空间,所以==比较的结果地址是一样的,返回true // 打印结果: //1977594184 //1977594184 //true TestB testb2 = new TestB(); TestB testb3 = new TestB(); boolean result2 = testb2.equals(testb3); System.out.println(testb2.hashCode());//testb2的hashcode System.out.println(testb3.hashCode());//testb3的hashcode System.out.println(result2); //因为TestB没有重写equals和hashcode方法,所以equals比较的是对象的引用地址,因为用的是Object父类的equals方法,查看源码可以知道比较的是引用地址 // 打印结果: //821045869 //1735488308 //false }}
&和&&运算结果是一致的,他们的区别在于:
if(a==1 & b ==2){};//这里两边都会判断一遍
if(a1 && b2){};//这里只有当a1成立才会接着判断b2,如果a1不成立,那么后面的b2不会去判断。
两者都为java多态的体现;
重载:方法名相当,参数的顺序,类型,个数不同,返回类型可以不同; PS:为什么不能根据返回类型不同来区分重载? answer:因为有返回值的方法可以选择不接收,当调用两个方法名一样的方法,其他相同,一个有返回值,一个没有返回值的时候,java编译器认为方法重复,不知道调用哪个;重写:方法名和参数完全一致,但构造方法,final和static修饰的方法不能被重写;访问权限不能比父类低
这个问题深究起来也是非常复杂的,这里简单的理解一下,java只有值传递;
当一个对象实例被当做参数传递到其他方法当中时,参数的值就是该对象的内存地址,该内存地址指向的堆内容是可以被改变的,也就是说对象当做参数传递,可以改变对象的内容。抽象类:abstract class
接口:interface简单的理解:abstract 用来定义一个抽象类,而interface用来定义接口;
abstract不能实例化; abstract类中可以有普通成员方法,也可以有abstract 修饰的抽象方法; abstract定义的abstract方法在子类必须有实现; abstract不能和static,native,synchronized同时使用,因为抽象类要有实现,可static不能被实现,native和synchronized都和方法实现相关;interface接口类中所有的的方法都没有方法体,都是抽象的,都必须在实现类中进行实现;
interface接口类中的所有成员变量都默认为public static final;一个类可以实现N个接口,但是只能继承一个父类;
hashmap允许key和value都为null,为非线程安全;
hashtable不允许,线程安全; 看一下源码: Hashtable.class:public synchronized V put(K var1, V var2) { if (var2 == null) { throw new NullPointerException(); } else { Hashtable.Entry[] var3 = this.table; int var4 = var1.hashCode(); int var5 = (var4 & 2147483647) % var3.length; for(Hashtable.Entry var6 = var3[var5]; var6 != null; var6 = var6.next) { if (var6.hash == var4 && var6.key.equals(var1)) { Object var7 = var6.value; var6.value = var2; return var7; } } this.addEntry(var4, var1, var2, var5); return null; } } hashtable用了syncchronized修饰,表示线程安全;
再来看一下hashmap的源码:
public V put(K var1, V var2) { return this.putVal(hash(var1), var1, var2, false, true); } final V putVal(int var1, K var2, V var3, boolean var4, boolean var5) { HashMap.Node[] var6; int var8; if ((var6 = this.table) == null || (var8 = var6.length) == 0) { var8 = (var6 = this.resize()).length; } Object var7; int var9; if ((var7 = var6[var9 = var8 - 1 & var1]) == null) { var6[var9] = this.newNode(var1, var2, var3, (HashMap.Node)null); } else { Object var10; Object var11; if (((HashMap.Node)var7).hash == var1 && ((var11 = ((HashMap.Node)var7).key) == var2 || var2 != null && var2.equals(var11))) { var10 = var7; } else if (var7 instanceof HashMap.TreeNode) { var10 = ((HashMap.TreeNode)var7).putTreeVal(this, var6, var1, var2, var3); } else { int var12 = 0; while(true) { if ((var10 = ((HashMap.Node)var7).next) == null) { ((HashMap.Node)var7).next = this.newNode(var1, var2, var3, (HashMap.Node)null); if (var12 >= 7) { this.treeifyBin(var6, var1); } break; } if (((HashMap.Node)var10).hash == var1 && ((var11 = ((HashMap.Node)var10).key) == var2 || var2 != null && var2.equals(var11))) { break; } var7 = var10; ++var12; } }
hashmap没有相关修饰,为非线程安全,高并发下,put可能会发生哈希冲突;ConcurrentHashMap为线程安全的map集合类,都属于java对象;
先写到这里吧,太晚了,睡了睡了
转载地址:http://cikmi.baihongyu.com/