Java关键字:
运算符:>>二进制位右移,如>>1表示右移一位,10>>1(00001010---> 00000101)变成5
<<二进制位左移,左移右侧补零。
static : 静态的,只能类名.访问
extends :继承,用于继承关系(class A extends B(){})
private : 私有的。用private修饰的属性只能在本类中直接
调用,出了本类需要用set和get方法进行访问和修改。
boolean :布尔类型。只有true和false两个变量,一个为真一个为假
instanceof :属于二元操作符用于判断左边的对象是否是右边的类型
例:if(A instanceof Cat) 如果A对象是Cat类型返回true 不是返回false
多用于向下转型判断
C c = new D();
if(c instanceof D){
D d1 = (D)c;
}
this :表示本对象,this.表示本对象的 this()用于构造方法中,只能有一个并且只能在第一行
用于无参构造方法调用有参构造方法完成初始化。一般可以省略
super :表示父类特征,super可以调用父类的构造参数,子类构造参数第一行会默认有super()
还可以用super.调用父类的方法或属性。this()和super()只能有一个。
final : 最终的,无法修改的 用final 修饰的类无法被继承,用final修饰的方法无法被覆盖
final修饰的局部变量,一旦被赋值,无法被修改(理解为常量)
final修饰的引用(将引用理解为变量)引用只能指向一个对象,并且只能指向该对象
但是对象内部数据仍然能够修改。
final修饰的实例变量再由static修饰,则为常量;
public static final String CHANGLIANG="常量语法";
abstract : 抽象类。只能被继承,无法创建对象。
抽象类可以没有抽象方法,但是抽象方法必须在抽象类中。
抽象类:public abstract class ChouXiangLei(){}
抽象方法: public abstract void chouXiangFangFa();
※非抽象类extends抽象类必须将抽象类里的抽象方法实现。
interface :接口。[修饰符列表] interface 接口名(){} 接口中只能包含常量或者抽象方法。
接口中抽象方法可以省略public abstract。接口中的都是公开的。 接口支持多继承。接口中常量public static final 可以省略。
接口有两种,一种是普通的接口,另一种是一个标志,没有方法,
只是一个标志性接口,没有方法,起到标识和标志作用,其作用
是给JVM,使其给它生成一个序列化版本号
implements: 实现。类实现接口。class A implements B{}
类和类之间的关系:is a :
Cat is a Animal(猫是一个动物)继承关系
A extends B{}
has a:
I has a pen(我有一个笔)表示关联关系 以属性形式存在
A{
B b;
}
like a:
cooker like a foodmenu(厨师像菜单)表示实现关系,类实现接口。
A implements B{}
三目运算符:方法? "true怎么样":"false的话怎么样";
数组(Array): 静态定义法:int[] a = {1,2,3,4};
动态初始化:int[] a = new int[10];
Array工具类: java.util.Arrays
冒泡排序: for(int i=a.length-1;i<0;i++){//n个数据循环n-1次
for(int j=0 ; j<i ;j++){//里面比较循环n-1-1次
if(a[j]>a[j+1]){
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
选择排序: for(int i=0;i<a.length-1;i++){
int min=i;
for(int j=i+1;j<a.length;j++){
if(a[i]<a[min]){
min = j;
}
}
if(min != i){
int t=a[min];
a[min]=a[i];
a[i]=t;
}
}
二分法查找: public static int binarySearch(int[] a,int ele){
int begin=0;
int end = a.length-1;
while(begin<=end){
int mid= (begin+end)/2;
if(a[mid]==ele){
return mid;
}else if(a[mid]<ele){
begin = mid+1;
}else{
end = mid -1;
}
}
return -1;
}
String类: String a="test";中a中储存的是"test"的内存地址,
所有""扩着的都是对象储存在方法区,常量字符串池中
StringBuffer类: 减少对象创建,方法区内存占用;
StringBuffer s = new StringBuffer();//初始化为长度为16的byte[]数组
//字符串拼接
s.append(填要追加的字符串);
优化StringBuffer方法初始化给够长度,减少数组扩容次数。
StringBuffer和StringBuilder区别,StringBuffer在
多线程环境是安全的
Date(日期类):使用 Date a = new Date();//表示此时系统时间
日期格式化 :其中yyyy:年、MM:月、dd:日、HH:时、mm:分、ss:秒、SSS:毫秒
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String a = sdf.format(传入Date的对象);
获取毫秒数:自1970-1-1 00:00:00 000 到系统现在时间所经历的毫秒数。
静态方法,使用类名.调用 返回一个long类型的值
long begin = System.currentTimeMillis();
DecimalFormat(数字类):数字格式化: ###,###.##表示加入千分位,保留两位小数
###,###.0000表示加入千分位,保留四位小数,不够补零
Random(随机数):产生随机数 Random r = new Random();
int random = r.nextInt();括号里可加数字,表示某一范围
如r.nextInt(101)表示在[0,100]之间产生随机数,不加的话代表在int范围内产生随机数。
enum(枚举):1.枚举一枚一枚举出来。
2.枚举是一个引用数据类型。
3.枚举类型如何定义,语法是?
enum 枚举名{
枚举值1,枚举值2(枚举值大写)
}
BigDecimal:财务系统使用精度更高。加减需要调用类中方法,无法直接加减。
Exception(异常处理):有两种方法:throws and try {} catch(){}
throws:上抛异常,将异常上抛给上一级调用者(没人处理最后会抛给JVM虚拟机,然后程序停止运行),
使用格式为:public static void **() throws 接异常名(如Exception等){}
throws只会抛出异常无法解决异常。
try{}catch(){}:捕捉异常,可以处理异常状况,
可以理解为:尝试运行括号中的代码,遇到异常停止运行try中代码跳到catch语句块中
使用格式:try{
尝试运行的代码块,遇见异常跳转到catch语句块,下面的语句不执行
}catch(异常类型 异常名称){
遇到错误执行的命令
}
异常中方法: 获取异常简单的描述信息:
String msg = exception.getMessage();
打印异常追踪的堆栈信息:
exception.printStackTrace();
使用实例:
public class ExceptionTest08 {
public static void main(String[] args) {
// 这里只是为了测试getMessage()方法和printStackTrace()方法。
// 这里只是new了异常对象,但是没有将异常对象抛出。JVM会认为这是一个普通的java对象。
NullPointerException e = new NullPointerException("空指针异常SSSSSS");
// 获取异常简单描述信息:这个信息实际上就是构造方法上面的String参数。
String msg = e.getMessage();
System.out.println(msg);
// 打印异常堆栈信息。
// java后台答应异常堆栈追踪信息的时候,采用了异步线程的方式打印的。
e.printStackTrace();
System.out.println("Hello World!");
}
}
finally : 接在try语句中,在里面的代码必定执行的,多用于对资源的释放。
try{
}catch(Exception e){
}finally{
}//执行顺序先执行try再执行finally最后执行catch,可以只有try和finally。
throw:手动抛出异常。throw new Exception("抛出异常");
定义一个异常:1.继承Exception或者RuntimeException
2.写一个无参构造方法,写一个有参构造方法,有参传一个String变量。
集合:实现Collection的类中分为List和Set,其中List有序可重复(存进去什么样取出来什么样);Set类中无序不可重复(存进去跟取出来顺序不一样)。放在集合中的元素需要重写equals方法。
******集合发生改变,迭代器要重新获取,不然调用next()方法会发生异常。
Collection方法:Collection c = new ArrayList();
1.add():将数据放入集合 例:c.add(100);
2.size():输出集合中元素个数 例:int a = c.size();
3.clear():清空集合 例:c.clear();
4.contains(Object a );判断集合中是否包含元素a,返回boolean类型数据 例:c.contains(a);判断时会自动调用equals方法。
5.remove():删除指定元素 例:c.remove(100);表示删除100这个元素,运行时调用元素的equals方法。
6.isEmpty():判断集合是否为空,返回boolean类型数据 例:c.isEmpty();true表示集合为空。
7.toArray():将集合转化为数组。例:Object[] obj= c.toArray();
集合遍历/迭代:以方法通用,在Collection中可以使用,但是MAP中不能使用。
Collection c = new HashSet();
//添加元素
c.add("abc");
c.add("ads");
c.add(100);
//获取迭代器
Iterator it = c.iterator();
//判断是否有元素可以迭代
if(c.hasNext()){
//如果有元素可以迭代,使用next方法返回对象。
Object obj = c.next();
}
Iterator中方法:boolean hasNext()如何仍有元素可以迭代,返回true
Object next()返回迭代下一个元素。
List中特有的方法: void add(int index, E element)在指定下标增加元素,使用不多,效率低
Object get(int index)根据下标获取元素
int indexOf(Object o)获取指定对象第一次出现处索引
int lastIndexOf(Object o)获取指定对象最后一次出现处索引
Object remove(int index)删除指定下标位置的元素
Object set(int index,Object element)修改指定位置的元素
Map常用方法:Map和Collection没有继承关系,Map集合以key和value形式存在,即键值对
1.void clear()清空Map集合
2.boolean containsKey(Object key)判断集合中是否包含某个key
3.boolean containsValue(Object value)判断集合中是否包含某个value
4.V get(Object key)获取对应key的value
5.boolean isEmpty()判断集合是否为空,返回boolean类型数据
6.Set<K> keySet()获取Map集合所有key,返回一个Set类型的集合
7.V put(K key,V value)向集合中添加键值对
8.V remove(Object key)删除key指定元素
9.int size()获取元素个数
10.Collection<V> values()获取所有value返回一个Collection
11.Set<Map.Entry<K,V>> entrySet()将Map集合转化为Set集合
HashMap初始容量16加载因子0.75当数据达到75%时开始扩容,初始化容量为2的倍数。JDK8之后如果哈希表单向链表中元素大于8个单项链表会变成二叉树,当二叉树节点数据小于6时会吧二叉树重新变成单向链表。HashMap线程非安全。
TreeMap:底层二叉树,遍历使用中序遍历,存进TreeMap key中的数据需要实现Comparator方法,或者写比较器
如果比较规则只有一个的时候,建议实现Comparable接口即类中对Comparable接口
如果比较规则多个,且需要频繁切换,则建议使用Comparator接口。即新写一个比较类实现Comparator接口。
Collections(集合工具类):
将集合变成线程安全的:Collections.sysnchronizedList(需要修改的集合);
排序:Collections.sort();自定义类需要实现Comparable接口。
IO流:I:Input O:Output 通过IO对硬盘的读和写
以内存为参照物,进内存叫输入(Input)。或叫读(Read)
出内存叫输出(Output)。或叫写(Write)
流的分类:输入流、输出流
字节流(万能流)、字符流(只能读txt文件)
流的四大家族:java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
以Stream结尾的是字节流,以Reader/Writer结尾的是字符流
java要掌握的流:
文件专属:
java.io.File(四种:InputStream、OutputStream、Reader、Writer)
转换流(字节流转换为字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
缓冲专属流:
java.io.Buffered(四种:InputStream、OutputStream、Reader、Writer)
数据流专属:
java.io.DataInputStream 数据字节输入流
java.io.DataOutputStream 写文件,可以吧数据类型写进去,但是只能拿DataFileInputStream拿出来
兵且要以数据的输入顺序一个一个输出
标准输出流:
java.io.PrintWriter
java.io.PrintStream
对象专属流:
java.io.ObjectInputStream
反序列化(DeSerialize):将硬盘上的数据重新恢复到内存当中,恢复
成Java对象。反序列化必须使其序列化版本号相同,版本号不同,无法
反序列化
Java判断是否相同,先看类名,类名相同,在看序列化版本号,只有
两个参数都相同才是同一个类。序列化版本号,是用来区分类的。
java.io.ObjectOutputStream
序列化(Serialize):将Java对象存储到文件中,将Java对象保存下来
的过程。多对象序列化需要使用集合,将对象存储到集合中,再将集合
序列化到硬盘中
***** 序列化只能序列化一个对象,第二个会报错,想要将多个对象序列化
需要存到集合中
***** 序列化要让需要序列化的类型需要实现Serializable,这个接口
只是一个标志性接口,没有方法,起到标识和标志作用。
接口有两种,一种是普通的接口,另一种是一个标志,没有方法,
只是一个标志性接口,没有方法,起到标识和标志作用,其作用
是给JVM,使其给它生成一个序列化版本号
由内存到硬盘是一个序列化过程,由硬盘到内存是一个反序列化过程
对象在序列化时会被切割为一个一个小文件传输到硬盘,在再硬盘中
组合起来
java.io.FileInputStream(文件字节输入流):万能的字节输入流,从硬盘中读取
java.io.File:1.File和四大家族无关,File无法完成文件的读写
2.File对象 是文件和路径名的抽象表示形式
File常用方法:boolean exists() 判断是否存在
void createNewFile() 以文件形式创建出来
void mkdir() 以目录的方式进行创建
void mkdirs() 以多重目录形式创建
String getParent() 获取文件父路径
String getAbsolutePath() 获取文件绝对路径
String getName() 获取文件名
boolean isDirectory() 判断是否为路径
boolean isFile() 判断是否为文件
long lastModified() 获取文件最后一次修改时间,自1970-1-1到现在毫秒数
String length() 文件大小,以字节数表示。
Flie[] listFiles() 获取当前目录下所有子文件
IO+Properties: 以后经常改变的数据直接存到文件中,用Properties进行读取
等号左边的为Key 右边的为Value
FileInputStream in = new FileInputStream("");//创建字节输入流
Map properties = Properties();//创建Properties集合
properties.load(in);//将文件中数据通过管道传给Properties对象
以上机制文件被称为配置文件
当配置文件格式为
Key = Value
时称为属性配置文件,这种文件建议以.properties结尾其中Propertis称
为属性配置文件的类。属性配置文件中重复的话会覆盖。
属性配置文件中#是注释,里面最好不要有空格,也可以用:隔开
System(系统类):System.gc 启动gc回收器
System.currentTimeMillis 自1970-1-1到现在所经历毫秒数
System.arraycopy() 拷贝数组
System.setOut() 将输出方向改为文件而不是控制台
泛型:在JDK5.0后的新特性,使用泛型是对集合元素进行指定
List<Animal> a = new ArrayList<Animal>();//对集合中数据类型进行指定,只允许存Animal类型的数据
优点:使用后使集合中数据更加统一了
在一定程度上不需要进行强制类型转换
缺点:使集合存储数据少了多样性。
JDK8.0后拥有新特性:自动推断
List<Animal> a = new ArrayList<Animal>();//后面的Animal可以不用写了,会进行自动推断
自定义泛型:在类后面加<自定义标识符>里面方法传自定义标识符,一般写E,或T
public class<自定义标识符>{
public void doSome(自定义的标识符 o){
System.out.println(o);
}
}
定义后不使用泛型,就会自动变成Object类型。
foreach(增强for循环):JDK5.0新特性
语法:for(元素类型 变量名:数组或集合){
System.out.println(变量名);
}
foreach缺点:没有下标,在需要使用下标的时候不建议使用。
transient(游离的):被其标识的变量不参与序列化。
serialVersionUID(序列化版本号):用来区分两个类是否为一个类,自动生成序列化版本号,会导致
后续代码不能修改,因为修改代码后序列化版本号会改变,所有要
手动添加序列化版本号
手动序列化:private static final long serialVersionUID = 1L(随意定);
Thread(线程):进程是一个应用
线程是一个进程中执行场景/执行单元
一个进程可以有多个线程
进程和进程之间内存资源不共享,线程和线程共享资源共享堆但是不共享栈,每有一个线程
多一个栈。
实现线程的方法:
1.写一个类继承Thread重写run方法,在主方法中New线程对象,调用对象.start()
方法启动线程,start方法主要任务是开辟一个新栈空间,代码执行后会瞬间结束
启动线程会自动调用run方法
public class MyThread exdent Thread{
public void run(){
}
}
MyThread my = new MyThread();
my.start();
2.编写一个类去实现Runnable接口(建议使用这种,因为继承只支持单继承)
public class MyRunnable implements Runnuble{
public void run (){
}
}
public static void main(String[] args){
MyRunnable m = new MyRunnable();
Thread t = new Thread(m);
t.start();
}
3.编写一个程序实现Callable接口,这种方法可以获取线程返回值
创建一个“未来任务类”
FutureTask ft = new FutureTake(new Callable(){
public Object call()throws Exception{
//需要实现的方法
}
});//这里采用了匿名内部类方法
Thread t = new Thread(ft);
Object obj = ft.get();//获取线程返回值,可能会导致main线程受阻,主线程
会等get方法执行结束后再执行下面的方法,缺点效率低,优点可以获取返回值。
线程在就绪<------>运行状态来回切换。
线程五大状态:
新建状态:刚new出来的线程对象
就绪状态:当start()执行后线程进入就绪状态
运行状态:run()方法执行抢到CPU时间片,进入运行状态,当时间片用完
再次进入就绪状态重新抢夺CPU时间片,再次抢到后接着执行上一次时间片
未执行完的任务。
阻塞状态:当一个线程在运行状态遇到阻塞事件,列如接受用户键盘输入等
方法,阻塞状态的线程会放弃之前抢占的CPU时间片。阻塞解除后会进入就绪
状态,重新抢夺时间片。
死亡状态:run()方法执行结束
线程方法:
void .setName("");//修改线程名字
String .getName();//获取线程名字,默认名字Thread-0~n 有一个加一
Thread c = Thread.curentThread();获取当前线程对象,静态方法,哪个线程执
行这个方法,返回哪个方法。
static void sleep(long millis);//让当前线程进入休眠,出现在那,谁执行
休眠。效果可以设置每隔多久执行一次
void interrupt();//干扰,使用异常中断睡眠
static void yield()让位,由运行状态转化为就绪状态
void join();线程合并,各个线程存在等待关系
终止线程:public class MyThread implements Runnuble{
boolean run = true;
//判断进程是否继续执行
if(run){
....
}else{
//return结束run执行即中断进程
return;
}
}
直接在main方法中new完线程后,想要终止直接.run = fales;就终止了
线程安全:解决线程安全,使用线程同步机制,实际上就是线程不并发了,线程排队执行
异步编程模型:线程并发(同时)执行
同步编程模型:线程排队执行
Java三大变量:
实例变量:在堆中
静态变量:在方法区中
局部变量:在栈中
只有局部变量不会存在线程安全问题
synchronized:
synchronized(多个线程的共享对象){
//需要排队的语句块
}
public synchronized void run(){}
出现在实例方法中锁的是this,不灵活并且可能会无故扩大
同步范围,这中方法不常用,如果同步的是this,则建议使
用在方法体中
守护线程:void setDaemo(true);设置为守护线程,当主线程结束,守护线程同样结束。
定时器:间隔特定的时间执行特定的程序
java.util.Timer Java类库中定时器类
生产者和消费者:Object有两方法wait()和notify(),两者因为是Object方法所以会被所有类继承
wait();//作用:让占用本对象对象锁的进程进行等待,并归还对象锁,且没有
notify唤醒则会一直等待
notify();//唤醒使用本对象的线程,但是不会释放对象锁
notifyAll();//唤醒所有使用本对象的线程
wait()和notify()一般与synchronized一同使用。
反射机制:
反射机制相关的类:
java.lang.Class//代表整个字节码
java.lang.reflect.Method//代表字节码中方法字节码
java.lang.reflect.Constructor//代表字节码中构造方法字节码
java.lang.reflect.Field//代表字节码中属性字节码
获取字节码的三种方式;
1.Class.forName("完整类名");
静态方法,方法参数一个字符串,字符串需要是完整类名,完整类名必须带有包名
Class c1 = Class.forName("java.lang.String");c1代表的是String.class文件
2.String b ="abc"
Class a = b.getClass();//每个类都继承了Object类都有getClass()方法。getClass()获取
Class文件
3.Class a = String.class;//每个类型都有.class属性。
反射机制作用:增加程序灵活度,降低程序耦合度,可以通过修改配置文件来创建不同的对象
只执行静态代码块 Class.forName("需要执行静态代码块的类名");
因为Class.forName()执行时进行了类加载。
src是类的根路径
获取文件的当前路径:
String path = Thread.curentThread().getContextClassLoader().getResource("文件名").getPath();
解释:Thread.curentThread()获取当前线程对象
getContextClassLoader()是线程对象的方法,可以获得当前线程的类加载器对象
getResource()[获取资源]类加载器方法,当前线程的类加载器默认从根路径下加载资源
以流的形式获取当前路径:
InputStream in = Thread.currentThread().getContextClassLoader().getResourecAsStream("文件名");
(重点)如何通过反射机制访问属性:
Class a = Class.forName("java.lang.String");//获取类
Object obj = a.newInstance();//调用无参数构造方法创建对象
Field field = a.getDeclareField("属性名");//获取属性
field.set(obj,属性值);给obj对象的属性赋值。
field.get(obj)//获取obj对象的属性值。
field.Accessible(true);//打破封装
可变长度参数:int...args (一定要为三个.)
可以传进去参数为1~n个,并且可变长参数只能出现一个并且只能是最后一个
可变长度参数可以当成数组看待。
(重点)通过反射机制如果调用方法:
CLass a = Class.forName("java.lang.String");
Object obj = a.newInstance();
Method b = obj.getDeclaredMethod("方法名",String.class,String.class);
b.invoke(obj,"方法参数");//调用方法
通过反射机制创建对象:
Class c = Class.forName();
Object obj = c.newInstance();
Constructor con = c.getDeclaredConstructor(int.class,String.class);//构造方法参数
Object newobj = con.newInstance(构造参数);//new有参构造对象
通过反射机制获取实现的接口和父类:
Class c = Class.forName("java.lang.String");
Class superClass = c.getSuperclass();//获取父类
Class[] interface = c.getInterfaces();//获取类实现的接口
ResourceBundle(资源绑定器):只能绑定.properties文件,且这个文件必须在类路径下
ResourceBundle bundle = ResourceBundle.getBundle("文件名");//只写文件名,不写properties
String className = bundle.getString("传Key名");
System.out.println(className);
Java中类加载器:程序在运行之前会启动类加载器,Java类加载器一共有三个
启动类加载器:首先加载jre/lib/rt.jre
扩展类加载器:通过启动加载器加载不到,会启动扩展类加载器会加载jre/lib/ext/*.jre
应用类加载器:如果扩展加载器也没有,那么应用类加载器会专门加载:classpath中的类。
Java为了保证类加载的安全,使用了双亲委派机制。
优先从启动类加载器,称为“父”
其次从扩展类加载器,称为”母“
最后才会从应用加载器加载。
网络编程:网络编程三要素:IP:用来定位计算机在网络中的位置
端口:用来定位应用在计算机中的位置
通信协议:交流规则
InetAddress类:表示互联网IP地址。
static InetAddress ip = InetAddress.getByName("ip地址或主机名");
static InetAddress ip = InetAddress.getLocalHost();//返回自己本地主机ip对象
String getHostAddress();//获取主机ip
String getHostName();//获取主机名
注解(Annotantian):
注解也叫注释,是一种引用数据类型
自定义注解:
[修饰符列表] @interface 注解类型名{
String name();//注解属性,如果写这个属性,使用时必须使用这个属性。
String age() default 25;//指定默认属性,使用注解时可以选择不指定属性值。
属性名是value的话使用时可以省略value。
}
注解使用:
注解使用语法格式:@注解类型名
注解可以出现在,类上,属性上,方法上,注解上等。
JDK注解:
Deprecated:表示以过时
Override:这个注解只能注解方法,这个注解是给编译器参考的,和运行阶段没关系
这个注解注解的方法必须是父类的方法,如果不是父类方法,报错,这个是标识型注解。
suppressWarnings:
元注解:
用来注解注解的注解
常见元注解:
Target:用来标注被标注的注解可以出现在哪些位置上。
@Target(Elementype.METHOD)表示被注解的注解只能出现在方法上。
Retention:用来标注最终保存在哪里
@Retention(RetentionPolicy.SOURCE)//只保存在Java源文件中
@Retention(RetentionPolicy.Class)//保存在Class文件中
@Retention(RetentionPolicy.RUNTIME)//保存在class中并且可以被反射机制读取到
面试题:
finally面试题:
public static int a(){ 反编译:
int a = 100; int i=100;
try{ int j=i;
return a; i++;
}finally{ return j;
i++;
}
}//最后返回100,自上而下执行。
这么多集合,用哪个集合最多?
答:ArrayList
因为ArrayList在末尾增加元素,和查找元素效率比较高,但是扩容效率比较低。
Thread sleep面试题:
在main方法中 new 一个线程对象如 Thread a = new MyThread();
a.sleep();
问a线程会进入休眠吗?
答:不会,因为sleep是静态方法,出现在哪里哪里休眠,虽然使用a去调,但是运行的时候
还会转化为Thread.sleep()。
IDAE快捷键:
Ctrl + D 复制一行
Ctrl + shift + F10 运行
Ctrl + shift + F12 全屏
Alt + insert 新建类,快速构造构造方法,和set and get方法。
Ctrl + shift + / 多行注释
Ctrl + / 单行注释
Ctrl + F12 查看函数属性和方法
Alt + 回车 查看错误,生成方法,导类
注:感觉csdn好坑,不知道是不是我自己太菜了,这篇文章的内容是我学习Java时的笔记,在文档中都弄好格式了,但是直接复制的博客上惨不忍睹,稍微优化了一下,应该还能看把,这不能带格式粘贴是真的难受。