Java初识

基础概念

特点

  • 完全面向对象,动态
  • 解释性,简易移植跨平台
  • 安全健壮高性能
  • 多线程分布式

三种核心机制

  • Java虚拟机 Java Virtual Machine
  • 垃圾收集机制 Garbage collection
  • 代码安全性检测 Code Security

注意,Java 语言是跨平台(write once run anywhere)的,JVM 不是跨平台的。Java 的跨平台通过 JVM 实现。

三大平台(技术架构)

  • JavaSE:Java Platform,Standard Edition,基础版
  • JavaEEJava Platform,Enterprise Edition,企业版
  • JavaMEJava Platform,Micro Edition,主要用于移动设备

关于 JVM - JRE - JDK

  • JVM ≈ 计算机系统(操作系统+硬件环境)
  • JRE(Java Runtime Environment) = java虚拟机 + 核心类库(辅助java虚拟机运行的文件)
  • JDK (Java Development Kit)= jre + java开发工具

关于 Java.exe - Javac.exe

  • Java.exe:java虚拟机解释并执行指定的class文件 (java 指定的class文件)
  • Javac.exe:java编译器对指定的java源文件进行编译 (javac java源文件)
  • Javap.exe:Java反编译器,javap -c -l -private 类名

关于 Java 的配置

  • JAVA_HOME
  • PATH
  • CLASSPATH

Java源文件结构

Java程序执行步骤: .java源文件,先编译 -> .class(与平台无关的字节码文件) -> 后解释,通过 JVM -> 特定平台的机器码 

  package packageName;
  import | import static packageName;
  public classDefinition | interfaceDefinition | EnumDefinition {}
  classDefinition | interfaceDefinition | EnumDefinition {}

:一个源文件中只能有一个public类,否则编译器找不到应该执行的main方法,但是一个源文件中可以有多个非public类。一个源文件中也只能有一个public接口。一个源文件中也只能有一个public枚举类。

关于访问修饰符

垃圾回收

只负责在合适时间回收堆内存中处于不可达状态的对象。强制(建议)进行垃圾回收方法:

  • System.gc() / runFinalization();
  • Runtime.getRuntime.gc() / runFinalization();

finalize:默认机制,Object 类的实例方法:  protected void finalize() throws Throwable  
虚引用:主要用于追踪对象被垃圾回收的状态。虚引用必须与引用队列联合使用 
JAR包 :Java 档案文件,Java Archive File。

  • 压缩,加快加载速度;
  • 包封装(工具类方法),安全,可移植;

注意事项

  • 格式:jar cvf jar文件名 class文件或文件夹
  • jar包打完后,要在清单文件中注明入口类(格式:Main-Class: 包名.类名)

 

Java类库

[修饰符] class 类名
{
    初始化块;成员变量;构造器;方法;内部类;
}

 [1]. Scanner
  基于正则表达式的文本扫描器:输入流、文件、字符串。
 [2]. System/Runtime 类 
  与程序的运行平台/运行时环境交互:环境变量、系统属性以及文件加载、垃圾回收和资源清理。
  System.identityHashCode(Object obj):根据指定对象的地址精确计算到的hashCode值,identityHashCode值唯一标识对象。
  Java 程序和 Runtime 实例一对一,getRuntime() 获取。Runtime 类可以单独启动一个进程运行操作系统的命令:rt.exec("命令");
 [3]. String/Math
 [4]. Random/ThreadLocalRandom
  减少多线程资源竞争,保证线程安全行性,静态 current() 方法获取 ThreadLocalRandom 对象。  
  Random rand = new Random(System.currentTimeMillis());
 [5]. BigDecimal
  解决 double 类型精度丢失问题、精确计算浮点数,创建方法:
  ·  基于 String 的构造器创建:new BigDecimal(String str);
  ·  以 double 参数创建:BigDecimal.valueOf(double value);
 [6]. Date/Calender
  Date 类不推荐使用。Calender 类是抽象类,静态方法 getInstance() 获取 Calender 对象,Calender 支持较好的容错性。注意,其 set() 方法有延迟修改的性质,可以避免触发多次不必要的计算。 
 [7]. 其他常用方法
  ·  MessageFormat:格式化字符串;
  ·  NumberFormat:格式化数字;
  ·  (Simple)DateFormat:格式化时间、日期;
   => DateTimeFormatter 格式器类:格式化日期时间、字符串解析;

继承 Inheritance ~ 多态 Polymorphism ~ 组合

类单继承,extends,Java类只能有一个直接父类。java.lang.Object类是所有类的父类。接口多实现,implements
java.lang.Object

  • Class<?> getClass():返回对象的运行时类;
  • protected object clone():高效、(浅)复制得到实例对象的副本;
class MyObj implements Cloneable {
    public MyObj clone(){
        return (MyObj)super.clone();
    }
}

Java规定:

  • 如果两个对象equals返回true,那么这两个对象的hashCode码必须一致
  • 在实际中,应该按需重写 Object 类的 equals() 和 hashCode() 方法

Objects 工具类:空指针安全的
[1]. Objects.requireNonNull(obj):对方法的形参作输入校验;    
protected ~ final
protected:允许子类重写父类方法,但不允许其他类访问,final是不允许子类重写父类方法。
final:[1]. 变量不可变,方法不可重写,类不能被继承; [2]. 定义宏变量;
不可变类
该类的对象创建后,对象的实例变量不可变。注意,包含引用类型成员变量的不可变类需要提供保护措施。
[1]. private final 成员变量;
[2]. 带参的构造器初始化[1]的成员变量,仅提供getter()方法;
this ~ super
this 是调用同一个类中重载的构造,super 是调用父类的构造器。
构造器 ~ 初始化块
对Java对象执行指定的初始化操作。构造函数是给相应的对象初始化操作。

初始化块在创建Java对象时隐式执行且在构造器之前。初始化块没有名字标识,修饰符只能为static,静态初始化块先于普通初始化块执行。

  • 初始化块,即构造代码块呢,是所有构造函数中的公共部分
  • 给所有的对象统一的初始化

关于构造代码块和构造方法的关系(最好通过反编译一个类来了解)

  • 成员变量的声明是在一个类的最前端
  • 成员变量的初始化、构造代码块的代码实际上是在构造方法中执行的(反编译可以看出)
    • 构造代码块的代码位于构造方法的代码的前面执行
    • 成员变量的初始化和构造代码块的执行是按照两者在类中的先后位置
    • 构造方法的代码实际上是最后执行的

instanceof ~ (type)
objA instanceof classB,判断引用类型对象objA是否是classB类或是其子类、实现类的实例。objA 的编译时类型要么是classB,要么与classB有父子继承关系,否则编译错误。 在强制类型转换(type)之前,先进行instanceof判断,避免出现ClassCastException异常。类似 C# 中的 is 运算符。

if(objA instanceof classB)
    classB objB = (classB)objA;

组合 ~ 继承
类的2种复用机制,组合是把旧类对象作为新类的(private)成员变量进行整合用于实现新类的功能,继承是(is-a)关系,组合是(has-a)关系;两者开销仅差一个private成员变量。
abstract ~ final ~ static ~ private
abstract类只能被继承,abstract方法必须由子类重写。
 [1]. abstract不能与final同时修饰类或方法;
 [2]. abstract不能与static同时修饰方法,但可以同时修饰内部类;
 [3]. abstract不能与private同时修饰方法;
接口 ~ 抽象类
抽象类:abstract,多个类的模板,模板模式;
接口:interface,多个类应遵守的公共行为规范,面向接口耦合和通信;
 [1]. 成员变量:静态常量,默认 public static final ;
 [2]. 方法:抽象方法,默认 public abstract,同时Java8允许在接口里定义默认方法(default)和类方法(static),注意接口没有构造方法
 [3]. 内部类,内部接口,内部枚举,默认 public static;

多态

数据成员:父类和子类有相同的成员变量,多态下访问的是父类的成员变量

  • 当父类和子类具有相同的非静态成员变量,多态下访问的是父类的成员变量,编译和运行参考左边
  • 当父类和子类具有相同的静态成员变量,多态下访问的是父类的静态成员变量,编译和运行参考左边

成员方法

  • 当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法(最常用的多态),编译看左边,运行看右边
  • 当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法,编译和运行参考左边

内部类

优点:成员内部类作为外部类的成员,可以访问外部类的任何成员

场景:A类和B类,A类想直接访问B类的成员,而B类又需建立A类的对象来访问A类中的成员。这时,应该将A类定义成B类的内部类。

作用域

  • 外部类:同一个包内(包访问权限)和任何位置(公共访问权限,public)
  • 内部类:同一个类(private)、同一个包(包访问权限)、父子类(protected)和任何位置(公共访问权限,public)

相互访问

  • 内部类可以直接访问外部类的成员属性
  • 外部类需要创建内部类的对象才能访问内部类的成员属性
    • 外部类的成员函数访问:Inner obj = new Inner()
    • 其他类访问:Outer.Inner obj = new Outer().new Inner() (若是静态内部类,应为 Outer.Inner obj = new Outer.Inner()) 

注意,内部类不能被外部类的子类重写(类的限定名肯定不同)。
非静态内部类
实例相关,非静态内部类对象里保存外部类对象的引用,依存于外部类对象;非静态内部类里不能定义静态成员(至于为什么,可以考虑类的加载过程,并参考 http://bbs.csdn.net/topics/90510249);
外部类访问内部类:(new innerClass()).innerVar;
非静态内部类的构造器必须通过外部类对象调用;非静态内部类的子类的对象也依存于外部类对象;
静态内部类
static,类相关,静态内部类对象保存外部类的引用,依存于外部类;接口的内部类默认是 public static;
外部类访问内部类:[1]. (new innerStaticClass()).innerVar;[2]. innerStaticClass.innerStaticVar;
静态内部类的构造器通过外部类调用; 
匿名内部类
匿名内部类不能重复使用,必须继承一个父类或实现一个接口。被匿名内部类访问的局部变量默认是 final。最常用的创建匿名内部类的情况是需要创建某个只有抽象方法的接口类型的对象。

注意,上面介绍的内部类都是成员内部类,还有一种特殊的内部类是定义在外部类的成员函数中,叫局部内部类,局部内部类只能访问该成员函数的 final 属性。

Lambda 表达式

Java8 引入 Lamba 表达式升级简化匿名内部类、匿名方法,允许创建函数式接口的实例。Lambda 表达式的目标类型能且必须是明确的函数式接口,函数式接口只能声明一个抽象方法。
[1]. 创建临时对象; [2]. 赋值;

格式:(形参列表)->{代码块/方法体}  

方法引用 ~ 构造器引用
当方法体只有一条代码时,可以用方法引用和构造器引用替代 Lambda 表达式。

格式:类名::类方法/实例方法/new  

本质:利用简洁的语法创建函数式接口的实例 关于匿名内部类和 Lamba 表达式的异同自行百度。

枚举

枚举类显式继承 java.lang.Enum 类,java.lang.Enum 类实现了 java.lang.Comparable 和 java.lang.Serializable 两个接口。

  • 非抽象枚举类默认 final 修饰,即不能派生子类
  • 枚举类的构造器默认 private 修饰
  • 枚举类的实例默认 public static final 修饰 
  • 枚举类中声明的每一个枚举值代表枚举类的一个实例对象
  • 声明枚举类时,也可以声明属性、方法和构造函数
  • 枚举类可以声明抽象方法,但是要有具体的枚举值去实现
  • 枚举类可以实现接口(序列化)、继承抽象类
  • 若枚举类只有一个枚举值,可以当作单例设计模式使用

1. public static <T extends Enum<T>> T valueOf(Class<T> enumType, string name)
静态方法,用于返回指定枚举类中指定名称的枚举值,以枚举类 SeasonEnum 为例:
  -- SeasonEnum se = Enum.valueOf(SeasonEnum.class, "SPRING" );
  -- SeasonEnum se = SeasonEnum.valueOf( "SPRING" );
2. 返回枚举常量名称、索引值
  -- SeasonEnum.SPRING;
  -- SeasonEnum.SPRING.name();
  -- SeasonEnum.SPRING.toString();
  -- SeasonEnum.SPRING.ordinal();  // 索引值 
3. 抽象枚举类
枚举类中利用 abstract 定义抽象方法,枚举类默认修饰为 abstract,同时每个枚举值必须显式实现抽象方法。

Java 集合

Java 集合分为 ListSetMapQueue 四种体系,接口 Collection 和 Map 是 Java 集合框架的根接口,List、 Set 和 Queue 接口派生于 Collection 接口。非类型安全,以 Object 类型存储,需要强制类型转换。 
Collection
 --  Iterator iterator():用于遍历集合元素;
 --  Object[] toArray():集合转化为数组;
 --  void removeIf(Predicate filter):批量删除满足条件的元素,入参为 Lambda 表达式;
 --  Stream stream(Predicate filter):返回集合对象对应的 Stream 对象;(Stream 编程,利用 Stream 对象的聚集操作简化对集合的操作),几个流式 API:
 [I]. filter(Predicate predicate):入参为 Lambda 表达式,过滤 Stream 对象中不符合条件的元素;
 [II]. toArray():将流 Stream 对象转换为数组;
 [III]. forEach(Consumer action):入参为 Lambda 表达式,遍历流 Stream 对象中的元素;
 
List:有序、可重复
线性表接口,提供索引访问、插入、删除、替换。额外方法,入参均可为 Lambda 表达式:

void sort(Comparator c); 
void replaceAll(UnaryOperator operator); 
ListIterator listIterator(); 

其中,ListIterator 接口继承于 Iterator 接口,增加了前向迭代功能,专用于操作 List。 

[1]. ArrayList(使用频率非常高) - Vector(线性安全的ArrayList)
List 接口的实现类,基于数组,默认长度10,每次扩容增长60%(1.5倍,(oldCapacity * 3)/2 + 1),封装了一个允许动态再分配的 Object[] 数组。ArrayList 非线程安全(单线程效率高),Vector 线程安全(多线程安全,效率低),性能低于 ArrayList。继承于 Vector 类的 Stack 子类也是线程安全的。推荐 Object get(int index) 随机访问元素。

[2]. LinkedList

类 LinkedList 既实现 List 接口,也实现 Deque 接口,基于链表。推荐 Iterator 迭代器随机访问元素。

Collection接口继承接口Iterable,Collection体系都具备获取自身迭代器的方法,只不过每个子类集合都进行了重写(因为数据结构不同)

ListIterator:List的特有迭代器,在迭代过程中支持添加或修改元素。而其他普通的迭代器,仅仅支持获取和删除操作。
小结:性能 ArrayList > LinkedList。

Queue:队列集合
提供 offer() 和 poll() 入队和出队。
[1]. Deque -> ArrayDeque
接口 Deque 继承于 Queue 接口,代表"双端队列",可以作为"栈"使用。
Iterator descendingIterator();逆向迭代双端队列 
类 ArrayDeque 既实现 Deque接口,也实现 List 接口,可以作为"栈"使用,基于数组
[2]. PriorityQueue
优先级队列,不允许 null 值。排序功能、元素非FIFO,排序方法参见 TreeSet。
Set:无序、不可重复
[1]. HashSet -> LinkedHashSet
HashSet 是 Set 接口的实现类,非线程安全。底层哈希表实现,按 Hash 算法 存储元素(根据元素的 hashCode 值计算存储位置并判重),元素值可以为null,存取和查找速度快。2 个 HashSet 元素相等的充要条件:

obj1.hashCode()==obj2.hashCode() && obj1.equals()==obj2.equals();  

元素的哈希值通过元素的hashcode方法获取,首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法,如果equls为true,视为同一个元素,如果equals为false就不是同一个元素(存储位置:同一个hashCode位置上可以存放多个元素。)。

:为保证 HashSet 功能的实现,hashCode() 和 equals() 方法是否重写需要保持同步。
~> LinkedHashSet
HashSet 的子类。利用链表维护元素的插入顺序,性能略低于 HashSet。
[2]. SortSet -> TreeSet
TreeSet 是 SortedSet 接口的实现类。按 红黑树 的数据结构有序存储同类型元素:

  • 自然排序:默认排序,元素类本身必须实现 Comparable 接口的 int compareTo(Object obj) 方法。
  • 定制排序:容器类必须关联 Comparator 接口的 int compare(Object o1, Object o2) 方法。

当元素自身不具备比较性,或者元素自身具备的比较性不是所需的,此时需要让容器自身具备比较性。

定义一个类实现Comparator接口,实现compare方法,并将该接口的子类对象作为参数传递给TreeSet集合的构造函数。

class MyComparator implements Comparator {
	public int compare(Object o1, Object o2) {

        }
}

当Comparable比较方式及Comparator比较方式同时存在,以Comparator比较方式为主。

2 个 TreeSet 元素相等的充要条件: 

0 == this.compareTo(obj)  // 自然排序
0 == (Comparator对象 | Lambda表达式).compare(t1,t2)   // 定制排序

:为保证 TreeSet 功能的实现,自然排序中 compareTo() 和 equals() 方法须保持同步。
~> SortedSet
SortedSet 接口继承自 Set 接口。
[3]. EnumSet
枚举类型元素的有序集合类,以枚举值在 Enum 类中的定义顺序决定集合中元素的顺序,元素不允许为null。Enum 对象在内部以 位向量 的形式存储,紧凑高效、占用内存小、运行效率好。

EnumSet es = EnumSet.Allof/noneOf(Season.class);     

小结EnumSet 是所有 Set 实现类中性能最好的,性能 HashSet > TreeSet。HashSet、TreeSet、EnumSet 均线程不安全。

Map:映射集合
关系一对一, Map 的 key 值集合是 Set,value 集合是 List,Map 提供 Entry 内部类封装 key-value对,通过 get(Object key)/remove(Object key) 获取和删除元素。
HashMap - Hashtable -> LinkedHashMap
HashMap 非线程安全、key和value 允许为 null,Hashtable 线程同步安全,key和value 不允许为 null,性能 HashMap > Hashtable。2 个 key 值相等的充要条件:

obj1.hashCode()==obj2.hashCode() && obj1.equals()==obj2.equals();  

2 个 value 相等的充要条件:

obj1.equals()==obj2.equals();

:为保证 HashMap-Hashtable 功能实现,hashCode()和equals()方法是否重写需保持同步。
~> LinkedHashMap
HashMap 的子类。利用双向链表维护元素的插入顺序,性能略低于 HashSMap。
~> Properties
Hashtable 的子类,key和value 均为 String 类型的 Map,store()和load() 存储和加载 属性文件。
SortedMap -> TreeMap
类 TreeMap 是 SortedMap 接口的实现类。按 红黑树 有序存储同类型元素:参考 TreeSet。
EnumMap
内部以数组形式保存,紧凑高效,key 值不能为 null,必须与枚举类关联。
小结:性能 HashMap > TreeMap,EnumMap 性能最好。
 
Iterator:迭代器,必须依附于 Collection 对象
 - boolean hasNext():
 - Object next():
 - void remove():用于删除集合里 next() 方法上一次返回的元素;
 - void forEachRemaining(Consumer action):利用 Lambda 表达式遍历集合元素;
:Iterator 迭代器采用 fast-fail 快速失败机制,迭代 Collection 集合时,集合元素不能被修改,否则立即抛出 ConcurrentModificationException 异常。


Collections:集合工具类,静态方法
[1]. 排序、查找、替换等
 - void sort/reverse/swap/shuffle/retate(List list): 排序/反转/交换/随机排序/旋转
 - int binarySearch(List list, Object key):二分查找
 - void fill(List list, Object obj):元素填充
 - boolean replaceAll(List list, Object oldObj, Object newObj):元素替换
[2]. 同步控制
提供 synchronizedXxx() 方法将指定集合包装程线程同步的集合,解决多线程并发访问集合时的线程安全问题。

Arrays:集合工具类,静态方法

泛型 Generic

类型安全检查,避免引起 ClassCastException 异常。以泛型List为例,类型通配符 List<?> 可以表示各种泛型List的父类,设定类型通配符的上限 List<? extends 父类> 限制其只表示某一类泛型List的父类,注意使用了类型通配符的集合不允许添加元素。通配符用于支持灵活的子类化。 
关于泛型,注意以下几个问题:
  • Java 不支持泛型数组
  • 泛型类型必须是引用类型(泛型集合不能存储基本数据类型,须使用基本数据类型的包装类,int ---> Integer)

参考
[1]. 泛型知识点总结
[2]. Java总结篇系列:Java泛型

异常

Java 的异常机制主要依赖于 try,catch,finally,throw,throws 五个关键字。其中,finally 用于回收在 try 块中打开的物理资源,throw 用于自行抛出异常的实例,throws 用于方法签名中声明该方法可能抛出异常、并由上一级调用者处理该异常。Java 的非正常情况有 2 类:Error 和 Exception,均继承于 Throwale 类。
Runtime 异常(运行时异常),RuntimeException 类及其子类的实例,灵活易用。

Java的异常体系

所有的异常类均在 java.lang 包中。

其中,Throwable 描述错误和异常,Error(错误)表示不可治愈,Exception(异常)表示可治愈,异常包括运行时异常和非运行(编译)时异常。

异常处理方式

  • 在出现异常的方法中显式捕获异常并处理,方法的调用者不会捕获到异常;
  • 在方法签名中用 throws 声明抛出异常,异常捕获之后交由调用者处理该异常;

优点

  • 正常业务代码和异常处理代码分离
  • 程序容错性,健壮、易维护;
  • 提供多异常捕获功能;

使用注意

  • 异常处理结构 try 块是必须的,catch 和 finally 块可选但必须至少二选一;
  • finally 块总会执行,return 都不能停止 finally 的执行,除非 try 或 catch 块中调用了 System.exit(1); 退出虚拟机;
  • 子类异常在前,父类异常在后,即先处理小异常,后处理大异常;

自定义异常 :自定义异常类需要提供 2 个构造器。

 1 public class MyException extends Exception | RuntimeException
 2 {
 3     public MyException(){}
 4     public MyException(String msg){
 5         this.super(msg);
 6     }
 7     public MyException(Throwable t){  // 支持异常的链式处理
 8         this.super(t);
 9     }
10 }

异常链 :链式处理
  捕获 1 个异常后接着抛出另一个异常,同时把原始异常的信息保存下来的机制。

图形用户界面编程 (了解即可)

 GUI(Graphic User Interface)编程,图形界面组件库(AWT + Swing)+ 事件处理机制。
· AWT,抽象窗口工具集,Abstract Window Toolkit。 基本的窗口框架,重量级组件、依赖底层平台;
· Swing,轻量级组件,100% Java 实现,跨平台性能好。采用 MVC 设计模式,实现 GUI 组件的显示逻辑和数据逻辑的分离,灵活性好;

MySQL - JDBC

 关于 MySQL 的基础,请参考 MySQL 初识 - sqh
 关于 JDBC 的基础,请参考 JDBC 初识 - sqh

注解

 Annotation,接口,封装元数据,修饰程序元素、提供为其设置元数据的方法,允许在源文件中嵌入补充信息,类似 C# 中的特性。程序通过反射能获取指定元素的 Annotation 对象、进而提取注解中的元数据。Java 8 支持重复注解,需要 @Repeatable 修饰。访问和处理 Annotation 的工具为 APT,Annotation Processing Tool,对源代码文件进行检测,执行严格的代码检查。
 - java.lang 包下的基本 Annotation:
· @Override:限定子类必须重写父类的方法,只能修饰方法; 
· @Deprecated:标记已过时;
· @Suppress Warnings:抑制编译器警告;
· @Safe Varargs:专用于抑制堆污染 Heap pollution 警告;
· @FunctionalInterface:函数式接口声明,要求接口只能包含一个抽象方法,只能修饰接口;
 - java.lang.annotation 包下的 元Annotation:
· @Retention:指定 Annotation 的生命周期;
      RetentionPolicy.RUNTIME: 
      编译器将 Annotation 记录在 .class 文件中,运行时可以通过 JVM 或反射获取 Annotation 信息;
· @Target:指定 Annotation 修饰的目标程序元素,所有程序元素的父接口为 AnnotatedElement;
· @Documented:指示被修饰的 Annotation 接口将被 javadoc 工具提取成文档;
· @Inherited:Annotation 具有父子继承性;
自定义 Annotation:默认继承 Annotation 接口

 public @interface AnnotationName{...} 

  其中,Annotation 定义中,成员变量必须以无形参方法的形式定义,可以用 default 指定初始值。
AnnotatedElement 接口:用于提取 Annotation 信息,实例方法
   -getAnnotation(xxx):获取程序元素上的指定注解;
   -getAnnotations(): 获取程序元素上的所有注解;
   -isAnnotationPresent(xxx)():判断程序元素上是否存在指定注解;

I/O

   具体参考 Java 输入输出体系学习 - sqh

多线程

   具体参考 Java 多线程学习 - sqh

网络编程 

   具体参考 Java 网络编程学习 - sqh


关于默认构造方法

  • 若类没有构造方法,java编译器为之添加默认构造方法,若有,不添加
  • java编译器为类添加的默认构造方法的访问权限与类的权限一样

泛型通配符 ?

限定泛型通配符的边界

  • 上边界:extends
  • 下边界:super 
? extends T:接收T类型或者T的子类型
? super T:接收T类型或者T的父类型

JDK5中的泛型允许在编写集合代码时,限制集合的处理类型,从而把原来程序运行时可能发生问题转变为编译时问题,提高程序可读性和稳定性。  

关于数据类型间的强制类型转换

一个数字,若没有类型标识,默认是 int 类型

// 会进行强制类型转换,如果超出类型能表示的范围,会报错,反之不会
byte b1 = 10;  // ok
byte b1 = 1000;  // 编译失败

byte b1 = 10;   byte b2 = 20;
byte b3 = 10 + 20;   // ok
byte b3 = b1 + b2;   // 编译失败

b2 = b1 + b2;   // 编译失败
b2 += b1;   // ok, Java 编译器已经默认对 += 进行强制类型转换

== 与 equals()

  • ==:值相等(基本数据类型)、两个引用是否指向同一(内存)对象(引用数据类型);
  • equals():Object默认提供的equals()方法等效于 ==,实际中按需重写;

直接量 “hello” 与 new String(“hello”)

  • “hello” 是编译时常量,常量池管理之,在常量池中存在且唯一;
  • new String(“hello”) 是运行时先用常量池管理 “hello” 直接量,再构造一个新的String对象存在堆中,实际上一共产生了2个 “hello” 字符串对象,返回值指向堆内存中的字符串对象;

构造器new 与 valueOf()

  • new 构造器创建全新对象
  • valueOf创建全新对象并缓存

后自增/减在JVM中的运行原理

int i = 0;
[1]. i++;    // i = 1
[2]. i = i++;   // i = 0

JVM会先声明一个临时变量保存自增/减之前的值,最后返回该值作为表达式的值

第一步:int temp = i;   // temp = 0;
第二步:i++;   // i = i + 1;
第三步:return temp, 作为表达式的值

注意,i 在该过程中的变化:i = 0 ------> 1 ------> 0 

Static

静态修饰符,其成员在方法区(数据共享区),优先于对象存在,作为对象的共享数据。

  • 静态方法只能访问静态变量,也不能使用 this、super 关键字
  • 静态代码块优先于普通代码块优先于构造函数,用于对类初始化
  • 静态变量/方法/代码块随着类的加载而加载,随着类的消失而消失

关于实例变量和静态变量

  • 存放位置:类变量随着类的加载而加载存在于方法(共享)区中,实例变量随着对象的建立而存在于堆内存中
  • 生命周期:类变量与类同在,实例变量与对象同在

 

Eclipse

关于快捷键

Alt + /:内容提示       Ctrl + 1:快速修复,编译异常提示      Ctrl + shift + O:导包
Ctrl + /:单行注释      Alt+上下键:代码位置切换                Ctrl + Shift + F:格式化代码块
Ctrl+Shift+/或\:多行注释    Ctrl+Shift+X/Y:大小写转换
查看源代码:(1)Ctrl+单击 需要查看源码的类;(2)Ctrl+Shift+T

  

 

 

posted @ 2016-08-09 23:23  万箭穿心,习惯就好。  阅读(254)  评论(0编辑  收藏  举报