1.1 Java介绍
(1)Java语言足够简单。
(2)Java是一门面对对象的编程语言
(3)Java是为数不多的多线程编程语言
(4)Java提供了自动的垃圾回收机制,以更好的处理垃圾空间
(5)Java避免了复杂的指针问题,而使用了使用了更加简单的引用处理来完成内存空间的匹配问题
(6)Java可以实现任意平台的移植
1.2 JDK的安装与配置
JRE包括Java虚拟机、Java核心类库和支持文件,JDK包含开发工具和编译器
1.3 第一个Java程序
Java程序分为两个操作
1.编译程序:javac Hello.java,此时会形成Hello.class文件,这就属于字节码文件
2.解释程序:java Hello
所有Java程序都有一个最为核心的单元:类
public class 类名称{}:文件名称必须与类名称保持一致,一个java文件只能有一个public class
class 类名称{}:文件名称可以与类名称不一致,但是生成的.class文件和类名一致,java文件里面可以有多个class,但是编译后会生成多个不同的.class文件
1.4 CLASSPATH环境属性
PATH:是属于操作系统路径,定义所有可执行程序的路径
CLASSPATH:是Java程序解释类文件时所使用的加载路径
CLASSPATH主要目的是定义类的加载路径
安装一些程序可能去修改已经设置好的CLASSPATH,可能导致你的程序无法正确执行,所以要进行手工修改
2.1 Java注释
// 单行注释
/* … / 多行注释
/* … */ 文档注释
尽可能使用单行注释,原因:在一些开发工具里面,多行注释格式化后的效果不好
2.2 标识符与关键字
2.3 数据类型划分
基本数据类型不牵扯到内存分配问题,而引用数据类型
基本数据类型
数值型
整型:byte short int long
浮点性:float double
字符型:char
布尔型:boolean
引用数据类型:数组、类、接口
2.4 运算符
2.5 程序逻辑控制
2.6 方法的定义及使用
方法重载的时候重点是根据参数类型以及个数来区分方法
##第三章
###String类操作方法
//字符与字符串
public String(char[] value)
public String(cahr[], int offset, int count)
public char charAt(int index)
public char[] toCharArray()
//字节与字符串
public String(byte[] bytes)
public String(byte[] bytes, int offset, int length)
public byte[] getBytes()
//字符串比较
public boolean equals(String anObject)
public boolean equalsIgnoreCase(String anObject)
public booean int compareTo(String anObject)
//字符串查找
public boolean contains(String s)
public int indexOf(String str)
public int lastIndex(String str)
public boolean startWith(String prefix)
public boolean endWith(String suffix)
//字符串替换
public String replaceAll(String regex, String replacement)
public String replaceFirst(String regex, String replacement)
//字符串截取、拆分
public String substring(int begIndex)
public String[] split(String regex)
//其他方法
public String concat(String str)
public String toLowerCase()
public String toUpperCase()
public String toUpperCase()
public String trim()
public int length()
public String intern()
public boolean isEmpty()
this调用构造方法的时候一定要放在代码的首行且一定要留有调用的出口
在java
中主要存在4块内存空间
类名.变量
调用说明
###代码块
###内部类
##第四章 面对对象高级知识
###继承
###覆写
子类覆写父类的方法,函数名、返回值、参数类型、参数个数要一模一样(这一点是区别与重载的)
关于覆写方法的执行问题
被子类覆写的方法不能比父类有更严格的访问权限(但是可以父类中的私有方法,在子类中是以public形式出现的,此时子类中的方法和父类的方法是两个完全不一样的东西)
this和super的区别:super只会在父类中寻找对应的属性和方法,this会优先找本类的属性和方法,找不到再去父类找
多态性分为方法的多态和父子类对象的转换
A a = new B(); a.print();
目的是参数的统一,子类实例化后的父类只能调用父类中定义过的方法A a = new B(); B b = (B)a; b.print()
父类可以调用子类中定义过单父类中没有定义过的方法,也就是子类特有的方法,但会带来一定的操作隐患为了保证转型顺利通常使用instanceof判断一个对象是否是某个类的实例化对象
a instanceof A
a instanceof B
###抽象类
抽象类和接口的区别
Object类是所有类的父类
理论上任何的简单Java类都应该覆写以上的三种方法
装箱与拆箱操作
public class TestDemo {
public static void main(String args[]) {
Integer obj = new Integer(10);
int tmp = obj.intValue();
System.out.println(tmp);
System.out.println(obj);
}
}
自动装箱
public class TestDemo {
public static void main(String args[]) {
Integer obj = 10;
int tmp = obj.intValue();
System.out.println(tmp);
System.out.println(obj);
}
}
包装类默认值null
所以Object类可以引用任何数据类型
##第五章 包及访问控制权限
包实际上指的就是文件夹
javac -d . Hello.java
package com.yootk.util
导入包的路径
import com.yootk.util.Message
导入包中的指定类,也可以使用*导入所有类 (不存在导入的性能上的问题)
public class 和 class的区别
学习参考
主要是用来打包*.class文件的
简单理解为private只能在一个类中访问,defalut只能在一个包中访问,protected在不同包的子类中访问,public为所有的都可以
构造方法私有,在类中使用private static classname = new classname()初始化一个对象,多例模式无非是在单例模式中多增加几个private static 对象,然后类中的方法都是static方法
try {
// 可能出现异常的代码段
} catch (异常类 对象名){
// 异常的处理
} finally {
// 最后都会执行这个
}
异常处理的格式:try…catch…finally、try…catch、try…finally
所有的异常类都会提供printStackTrace()方法,用来输出异常信息
java.lang.Object
|- java.lang.Throwable
|- java.lang.Exception
|- java.lang.RuntimeException
|- java.lang.ArithmeticException
throws关键字主要在方法定义上使用,表示此方法不进行异常处理,而是交给被调用处处理
class Math {
public static int div(int x, int y) throws Exception {
return x / y;
}
}
public class TestDemo {
public static void main(String args[]) {
try {
System.out.println("Math.div(10, 2)");
} catch (Exception e) {
e.printStackTrace();
}
}
}
强行抛出异常:考虑代码的统一性,所以不管调用方法时是否产生异常,都必须进行异常处理的操作
之前所有的异常类对象都是由JVM自动进行实例化操作的,而用户实际上可以自己抛出一个实例化对象的
try {
throw new Exception("123");
} catch (Exception e) {
e.printStackTrace();
}
异常处理关键字讲解
最大的特征:程序在编译时不会强制性要求用户处理异常,但是如果没有处理异常又发生了异常那么就会交给JVM进行默认处理
RuntimeException和Exception的区别
其主要功能是进行一个断言
public static void main(String args[]) {
int num = 10;
assert num == 20 : "num的内容不是20";
System.out.println("num = " + num);
}
java默认是不开启断言的,javac的时候加上-ea参数才会开启断言
菜鸟教程
入门教程
public void function(int ... num)
可以直接传多个参数,甚至可以传数组
for (数据类型 变量 : 数组 | 集合)
内容依次取出,可以避免索引问题
import static 包.类.*
就类似于在主类中定义static方法一样
class Point {
private Object x;
private Object y;
public void setX(Object x) {
this.x = x;
}
public void setY(Object y) {
this.y = y;
}
public Object getX() {
return this.x;
}
public Object getY() {
return this.y;
}
public String toString() {
return "Object x = " + this.x + " Object y = " + this.y;
}
}
public class TestDemo {
public static void main(String args[]) {
Point p = new Point();
p.setX("123");
p.setY(10);
String x = (String)p.getX();
String y = (String)p.getY();
System.out.println(p);
}
}
泛型的引入主要是为了解决对象向下转型并不是安全的问题
class Point<T> {
private T x;
private T y;
public void setX(T x) {
this.x = x;
}
public void setY(T y) {
this.y = y;
}
public T getX() {
return this.x;
}
public T getY() {
return this.y;
}
public String toString() {
return "Object x = " + this.x + " Object y = " + this.y;
}
}
public class TestDemo {
public static void main(String args[]) {
Point<String> p = new Point<String>();
p.setX("123");
p.setY(12);
String x = p.getX();
String y = p.getY();
System.out.println(p);
}
}
像这种情况编译期间就会检查出错误,使用泛型后类中的属性都是动态设置的,从而解决了对象转换的安全隐患
如果不设置泛型类型的话会默认使用Object对象
比如一个泛型类定义了多个不同数据类型的泛型对象,在进行方法调用的时候为了统一参数我们可以使用通配符
public static void fun(Message<?> tmp) {
System.out.println(tmp);
}
// 这样无论你传Message、Message都可以进行操作
通配符的上下限
两种实现方式
interface IMessage<T> {
public void print(T t);
}
class MessageImpl<S> implements IMessage<S> {
public void print(S s) {
System.out.println(s);
}
}
interface IMessage<T> {
public void print(T t);
}
class MessageImpl implements IMessage<String> {
public void print(String s) {
System.out.println(s);
}
}
public static T fun(T t) {
return t;
}
enum Color {
RED, GREEN, BLUE;
}
public class TestDemo {
public static void main(String args[]) {
Color tmp = Color.RED;
System.out.println(tmp);
}
}
class Color {
private String title;
private static final Color RED = new Color("RED");
private static final Color GREED = new Color("GREED");
private static final Color BLUE = new Color("BLUE");
private Color(String title) {
this.title = title;
}
public static Color getInstance(int ch) {
swich(ch) {
case 1:
return RED;
case 2:
return GREED;
case 3:
return BLUE;
default:
return null;
}
}
public String toString() {
return this.title;
}
}
public class TestDemo {
public static void main(String args[]) {
}
}
可见枚举的作用其实就是简化多例设计模式
Enum类的定义方法
public abstract class Enum
for (Color c : Color.values())
@Override 方法覆写
@Deprecated 方法过期 使用会有警告
@SuppressWarnings 压制警告信息
接口是解决多继承的主要手段
JDK1.8之前只能定义全局常量和抽象方法,现在可以定义default方法和static方法
JDK1.8之后引入的特性,指的是应用在单一抽象方法(Single Abstract Method, SAM)接口环境下的一种简化定义形式,可以用于解决匿名内部类的定义复杂问题
匿名内部类和Lambda表达式的比较
//匿名内部类
interface IMessage {
public void print();
}
public class TestDemo {
public static void main(String args[]) {
fun(new IMessage() {
@Override
public void print() {
System.out.println("l love ChenChen");
}
});
}
public static void fun(IMessage msg) {
msg.print();
}
}
//Lambda表达式
interface IMessage {
public void print();
}
public class TestDemo {
public static void main(String args[]) {
fun(() -> System.out.println("l love ChenChen"));
}
public static void fun(IMessage msg) {
msg.print();
}
}
(参数) -> 方法体
基本格式就是这样的
关于@Functionallnterface注解说明
Lambda已经明确是所在接口上进行的一种操作了,并且在接口中只允许定义一个抽象方法,而为了区分Lambda表达式的使用接口,可以在接口上使用"@Functionallterface"注解声明,这样就表示此为函数式接口,里面只允许定义一个抽象方法
除了对对象的引用操作,JDK1.8开始也支持在方法上进行引用
Java 8一共定义了四种操作形式
在方法引用过程中不管如何进行操作,对于可能出现的函数式接口的方法也最多只有4类:有参数有返回值、有参数无返回值、无参数有返回值、判断真假
如果想要实现多线程,以前要么继承Thread类要么实现Runnable接口,JDK1.5之后引入了新的Callable接口
java.lang.Thread,任何类只需要继承Thread类就可以成为一个线程的主类,线程启动就必须覆写Thread类中的run()方法,并且多线程启动的唯一方法就是Thread类中的start()方法
Thread类部分方法
public synchronized void start() {
if (threadStatus != 0) {
throw new IllegalThreadStateException();
}
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
private native void start0();
Lambda表达式
@FunctionalInterface
public interface Runnable {
public void run();
}
public class TestDemo {
public static void main(String args[]) {
String name = "thread target";
new Thread(() -> {
for (int i = 0; i < 200; ++i) {
System.out.println(name + "-->" + i);
}
})
}
}
两种方式实现多线程
class MyThread1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; ++i) {
System.out.println(i + " l love ChenChen");
}
}
}
class MyThread2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; ++i) {
System.out.println(i + " l like ChenChen");
}
}
}
public class TestDemo {
public static void main(String args[]) {
MyThread1 a = new MyThread1();
MyThread2 b = new MyThread2();
a.start();
// a.start();
// new Thread(a).start();
new Thread(b).start();
}
}
Runnable接口实现多线程可以避免单继承的局限,但是它的run()方法不能返回操作结果,所以为了解决这样的问题在JDK1.5引入了一个新的接口,java.util.concurrent.Callable
@FunctionlaInterface
public interface Callable<V> {
public V call() throw Exception;
}
返回的类型由Callable接口上的泛型动态决定 ,写完多线程主体类之后,要利用Thread类启动多线程,但是Thread类中并没有定义任何构造方法可以直接接收Callable接口对象实例,并且由于需要接收call()返回值的问题,从JDK1.5开始,Java提供了一个java.util.concurrent.FutureTask< V >类,定义如下
public class FutureTask
而RunnableFuture接口又同时实现了Future和Runnable接口
// FutureTask -> RunnableFuture -> Runnble
// -> Future
class MyThread implements Callable {
private int tickets = 10;
@Override
public String call() throws Exception {
for (int i = 0; i < 100; ++i) {
if (this.tickets > 0) {
System.out.println("sall a ticket" + this.tickets--);
}
}
return "over";
}
}
public class TestDemo {
public static void main(String args[]) throws Exception {
MyThread x = new MyThread();
MyThread y = new MyThread();
FutureTask task1 = new FutureTask(x);
FutureTask task2 = new FutureTask(y);
new Thread(task1).start();
new Thread(task2).start();
System.out.println("A thread return result = " + task1.get()); //get()方法获取run()方法的返回值
System.out.println("B thread return result = " + task2.get());
}
}
public V get(long timeout,
TimeUnit unit)
throws InterruptedException,
ExecutionException,
TimeoutException
public static final int MAX_PRIORITY // 线程最高优先级,数值10
public static final int NORM_PROIORITY // 线程中等优先级,数值5
public static final int MIN_PRIORITY // 线程最低优先级,数值1
public final void setPriority(int newPriority) // 设置线程优先级
public final int getPriority() // 取得线程优先级
public static Thread currentThread();
public Thread(Runnable target, String name);
public final void setName(String name);
public final String getName();
public static void sleep(long millis) throw InterruptedException
进程在哪里?
每一个JVM运行就是一个进程,主方法只是其中一个线程,当一个类执行完毕,此进程会自动消失
- main线程:程序的主要执行,以及启动子进程。
- gc线程,负责垃圾手机
线程同步的两种方式
四种代码块:代码块、构造块、静态块、同步块
方法中完整的定义格式
[public | protected | private] [static] [final] [native] [synchronized] 方法返回值类型 方法名称(参数列表 | 可变参数)[throws 异常,异常 ...]
Object类对多线程的支持
// 线程等待
public final void wait() throws InterruptedException {}
// 唤醒一个线程
public final void notify() {}
// 唤醒全部等待线程
public final void notifyAll()
sleep()和wait()的区别?
- sleep()是Thread类中定义的static方法,表示线程休眠,将执行机会让给其他线程,但是监控状态依然保持,会自动恢复
- wait()是Object类中定义的方法,表示线程等待,一直到执行了notify()或notifyAll()后才结束等待
String类
public final class String extends Object implements Serializable, Comparable
StringBuffer类
public final class StringBuffer extends Object implements Serializable, CharSequence
关于CharSequence接口
接口里面提供了charAt()、length()方法
关于StringBuilder类、
和StringBuffer基本一样,只是StringBuffer类中定义的方法都是使用synchronized进行声明的,所以StringBuilder都是异步方法,线程不安全操作
在每一个JVM进程中,都会存在一个运行时的操作类的对象,而这个对象所属的类型几句是Runtime类
一些常用的方法
public static Runtime getRuntime()
public long maxMemory() // 返回最大可用内存大小
public long totalMemory() // 返回所有可用内存大小
public long freeMemory() // 返回所有空余内存大小
public void gc()
public Process exec(String command) throws IOException //创建新的进程
关于long型数据在两种情况下使用:表示文件可用内存大小,表示日期时间数字