…
Java 版本
JavaSE:标准版,桌面应用。
JavaEE:企业版。
JavaME:微系统版,嵌入式。
JDK
解压缩JDK,配置环境变量。
1 2 3 4 5
| JAVA_HOME=/path/to/jdk
CLASSPATH=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
PATH=PATH;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
|
主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Main { public static void sum(int... x){ int r=0; for(int i=0; i<x.length; ++i){ r+=x[i]; } return r; }
public static void main(String[] args) { System.out.println("Hello"); } }
|
说明注释
说明注释,以 /** 开始,以 */结束。
1 2 3 4 5 6 7 8 9 10
| @author 标识一个类的作者 {@inheritDoc} 从直接父类继承的注释 @version 指定类的版本
@param 说明一个方法的参数 @return 说明返回值类型 @serial 说明一个序列化属性 @exception 标志一个类抛出的异常 @throws 和 @exception标签一样 {@value} 显示常量的值,该常量必须是static属性。
|
数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| int arr[]; int[] arr;
int[] arr = new int[4]; int[] arr = new int[] {1, 2, 3, 4};
int[][] arr = new int[32][32]; int[][] arr = new int[32][]; int[][] arr = new int[][]{ {1, 2}, {3, 4} };
arr.length;
ArrayIndexOutOfBoundsException NullPointerException
|
集合
List
1 2 3 4 5 6 7 8 9
| add(e) add(index, e) remove(index) remove(e) get(index) size() toArray()
List list = Arrays.asList()
|
Map
1 2 3
| HashMap SortedMap # TreeMap
|
1 2 3 4 5
| put(k, v) get(k) containsKey(k) keySet() entrySet()
|
setting.properties 配置文件,不支持中文
1 2 3 4
| Properties props = new Properties(); props.load(new FileInputStream(filepath));
String url = props.getProperties("url", "default url");
|
Set
1 2 3
| HashSet SortedSet # TreeSet
|
1 2 3 4
| add(e) remove(e) contains(e) size()
|
自定义排序非法
1 2 3 4 5 6
| TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { return s1 > s2; } });
|
Queue
1 2 3 4 5 6 7 8 9 10
| size() isEmpty()
add() remove() element()
offer() poll() peek()
|
Deque
底层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| size() isEmpty()
addLast() addFirst() removeFirst() removeLast() elementFirst() elementLast()
offerLast() offerFirst() pollFirst() pollLast() peekFirst() peekLast()
|
Stack
不要使用遗留类Stack,而是使用Deque实现Stack
1 2 3 4
| push() peek() pop() isEmpty()
|
Iterator
1 2 3
| list.iterator() hasNext() next()
|
Collections
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| boolean addAll(Collection<? super T> c, T... elements) emptyList() emptyMap() emptySet() singleton() singletonList() singletonMap() sort(list) sort(list, Comparator<> c) shuffle(); unmodifiableList() unmodifiableSet() unmodifiableMap()
synchronizedList() synchronizedSet() synchronizedMap()
|
类和对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Animal { private int age;
public int getAge() { return age; } }
public class Main { public static void main(String[] args){ Animal a = new Animal(); new Animal().getAge(); } }
|
包
自定义包,包名要与路径名一样。
1 2 3 4 5 6
| package base.animal;
import Animal;
public class Cat{}
|
1 2 3 4 5 6 7 8
| import java.lang; import java.net; import java.io; import java.util; import java.text; import java.sql; import java.awt; import java.applet;
|
修饰符
1 2 3 4 5
| static final synchronized abstract native
|
JavaBean
一种可重用组件:
- public 属性
- 有一个公共的无参构造器
- 有属性,有 get set 方法
实例化过程
- 方法区:
- 栈区:
- 堆区:
- 栈区:
- 调用构造函数初始化
- 堆地址赋值给引用变量
- 构造函数出栈
多态
方法的重载和重写。
对象的多态性:子类对父类覆盖,包括抽象类,接口。
编译时的(声明的)类型与运行时的(存储的)类型不一致,就出现多态。
1 2 3
| Person p = new Student(); p.getInfo();
|
查看类型:
1 2 3
| Person p = new Student(); p instanceof Person; p instanceof Student;
|
Object
主要方法:
==
只有指向同一对象,类型匹配时才为True。
equals比较是否指向同一个对象,但是在File,Date,String以及包装类(Integer,Float之类)这些,是比较对象的内容,而不考虑是否是同一个对象。
包装类
JDK 1.5后支持自动拆箱,装箱。
装箱:
1
| Integer i = new Integer(10);
|
拆箱:
初始化块
程序初始化顺序:
- 声明成员变量,默认初始化。
- 显式初始化,执行初始化块。
- 调用构造器,初始化变量。
静态初始化代码块优先于非静态代码块。
1 2 3 4 5 6 7 8 9
| public class Test { { System.out.println(""); }
static { System.out.println(""); } }
|
Logger
1 2 3 4
| Logger logger = Logger.getGlobal(); logger.info(); logger.log(Level.WARNING, ""); logger.warning();
|
级别
1 2 3 4 5 6 7
| SEVERE WARNING INFO CONFIG FINE FINER FINEST
|
配置文件需要通过启动参数传递。
commons logging 是 Apache 创建的日志模块,可以自动挂载Log4j或JDK Logging。
1 2 3
| Log log = LogFactory.getLog(Main.class); log.info(); log.warn();
|
级别
1 2 3 4 5 6
| FATAL ERROR WARNING INFO DEBUG TRACE
|
LOG4J 分为 1x 2x
- 可以将日志输出到Console,File,Socket。
- 可以使用Layout格式化输出
- 使用Filter过滤要输出的内容
配置文件 - 需设置 log4j.xml
泛型
1 2 3 4 5 6 7
| class Pair<T> { public Pair(Class<T> clazz){ T c = clazz.newInstance(); } } <? extends Number> <? super Number>
|
注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
@Override
@Deprecated
@SuppressWarnings("all")
@Target
@Retention
@Documented
@Inherited
@Inherited @Documented @Retention(value = RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.TYPE}) public @interface MyAnno { String name() default ""; int age() default 0; String[] phones; String value(); }
|
反射
Class 类,是反射的核心类。创建一个类,内存中就对应生成一个Class对象,结构也会存在Class对象中。
功能:
- 对象所属类
- 访问对象的所有属性和方法
- 处理注解
- 对性能有影响
1 2 3 4 5 6 7 8 9 10 11 12
| Class c = Class.forName("java.lang.String"); getAnnotation(); getMethod(); newInstance(); getName(); getSuperClass(); getInterfaces(); getClassLoader(); getConstructors(); getMethod(String name, Class ...); getDeclaredFields();
|
获取Class对象的方法。
1 2 3 4 5
| Class c = Class.forName("java.lang.String"); Class c = Student.class; Class c = student.getClass(); Class c = Integer.TYPE;
|
可以创建Class对象的类型:
- 类
- 接口
- 数组
- 枚举
- 注解
- void
- 基本数据类型
程序 类加载过程:
- class文件加载到内存,并同时生成对应的Class对象
- 链接,初始化为 0
- 执行
<clinit>()
,合并所有的类内静态代码块,并执行。
类加载器:
- 引导类加载器:JVM自带的类加载器,用于装载核心类,无法直接获取。
jre/lib/rt.jar
- 扩展类加载器:
jre/lib/ext
- 系统类加载器:
java.class.path
CLASS_PATH
下的包,最常用
1 2 3 4 5
| ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); systemClassLoader.getParent(); systemClassLoader.getParent().getParent();
ClassLoader loader = Class.forName("java.lang.String").getClassLoader();
|
使用Class对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| Class c = Class.forName("java.lang.String");
c.getName(); c.getSimpleName();
Field[] fields = c.getFields(); Field field = c.getField("name"); Field[] fields = c.getDeclaredFields(); Field field = c.getDeclaredField("name");
Method[] methods = c.getMethods(); Method method = c.getMethod("getName", null); Method[] methods = c.getDeclaredMethods(); Method method = c.getDeclaredMethod("setName", String.class);
String str = (String)c.newInstance();
method.invoke(str, "123"); field.setAccessible(true); field.set(str, "321");
Typep[] genInfos = method.getGenericParameterTypes(); for(Type info: genInfos){ if(info instanceof ParameterizedType){ Type[] subInfos = ((ParameterizedType)info).getActualTypeArguments(); } }
Annotation[] annotations = c.getAnnotations(); Annotation annotation = c.getAnnotation(SuppressWarnings.class); SuppressWarnings swanno = (SuppressWarnings)annotation; Field field = c.getDeclaredField("name"); SuppressWarnings fsw = (SuppressWarnings)c.getAnnotation(SuppressWarnings.class);
swanno.value(); fsw.type();
|
Lambda
直接使用方法引用:
1 2 3
| Arrays.sort(array, SortedBy::ignoreCase); Arrays.sort(array, SortedBy::compareTo); Arrays.sort(array, SortedBy::new);
|
单元测试
1 2 3 4 5 6
| public class Test { @Test public void testFun() { assertEquals(3, 1+2); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| @Before @After @BeforeClass @AfterClass
@Test(expected=Exception.class)
@Parameters public static Collection<?> data() {return ...} @RunWith
@Test(timeout=1000)
|
编码与加密
编码
1 2 3 4 5 6 7 8
| URLEncoder.encode("123", "UTF-8"); URLEncoder.decode("%E5%8F", "UTF-8");
Base64.getEncoder().encodeToString("123".getBytes("UTF-8")); Base64.getDecoder().decode(b64, "UTF-8"); Base64.getUrlEncoder().encodeToString("123".getBytes("UTF-8")); Base64.getUrlDecoder().decode(b64, "UTF-8");
|
摘要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| MessageDigest md = MessageDigest.getInstance("MD5"); md.update("123".getBytes("UTF-8")); md.update(data2); byte[] result = md.digest();
MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update("123".getBytes("UTF-8")); md.update(data2); byte[] result = md.digest();
Security.addProvider(new BouncyCastleProvider()); MessageDigest md = MessageDigest.getInstance("RipeMD160"); md.update("123".getBytes("UTF-8")); md.update(data2); byte[] result = md.digest();
KeyGenerator keygen = KeyGenerator.getInstance("HmacMD5"); SecretKey skey = keygen.generateKey(); Mac mac = Mac.getInstance("HmacMD5"); mac.init(skey); mac.update(data); byte[] result = mac.doFinal();
|
加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| String CIPHER_NAME = "AES/ECB/PKCS5Padding"; Cipher cipher = Cipher.getInstance(CIPHER_NAME); SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); cipher.init(Cipher.ENCRYPT_MODE, keyspec);
return cipher.doFinal(input);
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH"); kpGen.initialize(512); KeyPair kp = kpGen.generateKeyPair(); privateKey = kp.getPrivate(); publicKey = kp.getPublic();
keySpec = new X509EncodedKeySpec(publicKeyBytes); kf = KeyFacotry.getInstance("DH"); publicKey = kf.generatePublic(keySpec); keyAgreement = KeyAgreement.getInstance("DH"); keyAgreement.init(this.privateKey) keyAgreement.doPhase(publicKey, true)
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA"); kpGen.initialize(1024); KeyPair kp = kpGen.generateKeyPair(); privateKey = kp.getPrivate(); publicKey = kp.getPublic();
Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(input);
|
签名
数字证书
线程
创建。
方法一:继承Thread类,重写run方法。
1 2 3
| public class MyThread extends Thread { public void run () {} }
|
方法二:实现Runnable接口
1 2 3
| public class MyThread implements Runnable { public void run() {} }
|
lambda方式:
1
| Thread thread = new Thread(() -> { });
|
线程方法:
1 2 3
| start() 启动 stop() 强制结束 join() 等待
|
异常:
线程间的共享数据,用volatile
修饰
守护线程:
线程同步
可以同步代码块
可以同步方法
1 2 3
| synchronized(lock) { }
|
基本类型赋值,引用类型赋值都是原子操作。
一般对于需要同步的数据,封装成对象,将其中的方法改为同步方法。此时锁住的则是this
或A.class
。
可重入锁:某个线程多次获取同一个锁。
多线程协调:
1 2
| this.wait() this.notify()
|
线程同步工具类:concurrent
ReentrantLock 需要手动释放的锁
1 2 3 4 5 6 7
| Lock lock = new ReentrantLock(); lock.lock(); lock.tryLock(); try{ } finally{ lock.unlock(); }
|
ReadWriteLock 读时可多线程同时获取锁,写时只允许一个锁
1 2 3
| Lock lock = new ReentrantReadWriteLock(); Lock r = lock.readLock(); Lock w = lock.writeLock();
|
Condition 实现wait、notify功能
1 2 3
| lock.newCondition(); await(); signalAll();
|
Concurrent 线程安全集合
1 2 3 4 5 6
| CopyOnWriteArrayList ConcurrentHashMap CopyOnWriteArraySet ArrayBlockingQueue LinkedBlockingQueue LinkedBlockingDeque
|
原子操作 CAS 操作
1 2 3 4
| AtomicInteger value; AtomicIntegerArray values; addAndGet(); get();
|
ExecutorService 线程池
Future 获取线程的返回值
1 2 3 4 5
| Callable<String> task = new Task(); Future<String> futrue = exe.submit(task); String s = future.get(); cancel() isDone()
|
CompletableFuture 任务结束后自动调用回调函数
1 2 3 4 5 6 7 8 9 10
| CompletableFuture<String> cf = getCompletableFutureFromSomewhere(); cf.thenAccept((result) -> {}); cf.exceptionally((exception) -> {});
cf2 = cf.thenApplyAsync(); cf3 = cf2.thenApplyAsync();
<Object>cf = CompletableFuture.anyOf(); <Void>cf = CompletableFuture.allOf(); cf.thenAccept();
|
Fork/Join 可以拆分任务为多个小任务并行计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class SumTask extends RecursiveTask<Long> { @Override protected Long compute() { SumTask sub1 = new SumTask(); SumTask sub2 = new SumTask(); invokeAll(sub1, sub2); res1 = fork1.join(); res2 = fork2.join(); return res1 + res2; } }
ForkJoinPool.commonPool().invoke(task); Arrays.parallelSort();
|
工具类
1 2 3 4 5 6 7 8
| Thread.currentThread();
static ThreadLocal<String> tl = new ThreadLocal<>(); tl.set(); String s = tl.get(); tl.remove();
|
Maven
要求代码目录命名规范。
依赖关系:
- compile
- test
- runtime
- provided 编译时需要,运行时不需要
网络编程
TCP
1 2 3 4 5 6 7 8
| Socket sock = new Socket(InetAddress, port); sock.getInputStream(); sock.getOutputStream();
ServerSocket sock = new ServerSocket(port); Socket sk = sock.accept(); sock.getInputStream(); sock.getOutputStream();
|
1 2
| bindAddr = InetAddress.getByAddress(new byte[] {192, 168, 1, 1}); ServerSocket sock = new ServerSocket(port, backlog, bindAddr);
|
UDP
1 2 3 4 5 6
| DatagramSocket sock = new DatagramSocket() sock.connect(addr, 9090); DatagramPacket packet = new DatagramPacket(data, data.length); sock.send(packet); resp = new DatagramPacket(buffer, buffer.length); sock.receive(resp);
|
HTTP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| URL url = new URL(""); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); int code = conn.getResponseCode(); try(InputStream in = conn.getInputStream()) { } conn.disconnect();
URL url = new URL(""); byte[] postData = "".getBytes("UTF-8"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-length", String.valueOf(postData.length)); try(OutputStream out = conn.getOutputStream()){ out.write(postData); } int code = conn.getResponseCode(); try(InputStream in = conn.getInputStream()) { } conn.disconnect();
|
Stream util
表示任意Java对象,用于内存计算,业务逻辑。实时计算,惰性计算。
可以存储无限个元素
可以转换为另一个Steam
1 2 3 4
| Stream<BigInteger> naturals = createNaturalSteam(); naturals.map((n) -> n.multiply(n)) .limit(100) .forEach(System.out::println);
|
1 2 3 4 5
| Stream<Integer> s = Stream.of(1,2,3,4,5); Stream<Integer> s = Arrays.stream(oneArray); Stream<Integer> s = oneList.stream(); Stream<T> s = Stream.generate(Supplier<T> s); Stream<String> lines = Files.lines();
|
Map 方法,对序列的每个元素施加一个操作
1
| Stream<Integer> s2 = s1.map((n) -> n * n);
|
Filter 方法,对每个元素测试过滤
1
| Stream<Integer> s2 = s1.filter((n) -> n % 2 == 1);
|
Reduce 方法,对元素聚合
1 2
| Stream<Integer> s2 = s1.reduce((acc, n) -> acc + n); Stream<Integer> s2 = s1.reduce(1000 , (sum, n) -> sum + n);
|
其他方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| sorted() distinct() limit() skip() concat() flatMap() parallel()
reduce() count() max() min() sum() average() allMatch() anyMatch()
forEach() toArray() collect()
|