JAVA

java8新特性

下载jdk地址
https://www.oracle.com/technetwork/java/javase/archive-139210.html
需要登录,选择对对应版本下载安装
windows环境变量配置
添加变量
JAVA_HOME=jdk安装路径
CLASSPATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar

追加path变量
%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin
Linux环境变量配置
export JAVA_HOME=/usr/local/jdk1.8.0_181-amd64
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME:$JAVA_HOME/bin
java版本查看
java -version
java安装目录查询
java -verbose,  查看最后一行即为JDK安装路径
线程池
实现Runnable接口、继承Thread类                      创建线程方式

Executors                                          创建线程池工具类
newCachedThreadPool                                缓存线程池
newFixedThreadPool                                 固定线程大小线程池
newSingleThreadExecutor                            单线程线程池
newScheduledThreadPool                             定时调度线程池

ThreadPoolExecutor                                 创建线程池类,参数如下
corePoolSize                                       核心线程数
maximumPoolSize                                    最大线程数
keepAliveTime                                      空闲时间
unit                                               空间时间单位
workQueue                                          任务队列
threadFactory                                      线程工厂
handler                                            线程拒绝策略(4)
AbortPolicy(异常终止,会抛异常,默认策略)
DiscardPolicy(丢弃新任务策略)
DiscardOldestPolicy(丢弃旧任务策略)
CallerRunsPolicy(主线程调用执行)

//新建仅有一个线程的线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new LinkedBlockingQueue(Integer.MAX_VALUE), new ThreadPoolExecutor.DiscardPolicy());
线程池任务使用示例
List<Callable<Object>> tasks = new ArrayList<>();
for (String str : Arrays.asList(new String[]{"a","b","c"})) {
 Callable<Object> task = ()->{
  System.out.println(str+":"+Thread.currentThread().getName());
  return str;
 };
 tasks.add(task);
}
ExecutorService threadPool = Executors.newFixedThreadPool(5);
threadPool.invokeAll(tasks, 10, TimeUnit.MINUTES);
threadPool.shutdown();
java自带缓存
<dependency>
 <groupId>com.google.guava</groupId>
 <artifactId>guava</artifactId>
 <version>26.0-jre</version>
</dependency>

Cache<String, Object> caches=CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(5, TimeUnit.MINUTES).build();
刷新机制:包括refresh和expire刷新机制
expireAfterAccess: 当缓存项在指定的时间段内没有被读或写就会被回收。
expireAfterWrite:当缓存项在指定的时间段内没有更新就会被回收。
refreshAfterWrite:当缓存项上一次更新操作之后的多久会被刷新。
锁机制
synchronized(可重入锁、jvm实现)                         //同步关键字
volatile(禁止指令重排序、保证线程可见性)
//可见性:缓存一致性协议
//禁止指令重排序:JMM模型里有8个指令完成数据的读写,通过其中load和store指令相互组合成的4个内存屏障实现禁止指令重排序

ReentrantLock(可重入锁、api实现、lock()、unlock())     //重入锁

ReentrantReadWriteLock(读写锁、不限制读限制写、api实现、readLock()、writeLock())
ReentrantReadWriteLock.WriteLocklock()、unlock())
ReentrantReadWriteLock.ReadLocklock()、unlock())

AtomicInteger.cas                                     //原子变量

wait、notify、notifyAll                               //线程的等待、通知机制

AQS (Template Method、AbstractQueuedSynchronizer)
CAS (Unsafe、ABA问题、加版本号、compareAndSet、compareAndSwap)
并发编程
CountDownLatch(N) countDown()、await()                //门闩
N减为0后,释放await()
等待其他多个任务执行完成后在执行此任务

CyclicBarrier(N, r)  await()                          //回环栅栏(可重用)
await调用N次后执行r方法后释放await()
所有任务都达到某个点后一起执行任务

Semaphore(N) acquire()、release()                     //信号量
对N个资源限制访问,看谁能获取到

ThreadLocal(set、get、数据存储在当前线程)
LockSupport(线程停止、唤醒、park()、unpark(thread))
IO流
InputStream、OutputStream                         //字节流基类
Reader、Writer                                    //字符流基类

FileInputStream、FileOutputStream                 //处理字节文件

FileReader、FileWriter                            //处理字符文件

ByteArrayInputStream、ByteArrayOutputStream       //处理字节数组

CharArrayReader、CharArrayWriter                  //处理字符数组

BufferedInputStream、BufferedOutputStream         //字节缓存流
BufferedReader、BufferedWriter                    //字符缓存流
lambda的几种常用方法
Consumer:             消费型接口,内有抽象方法—void accept(T t)
Supplier:             生产型接口(供给型),内有抽象方法—T get();
Function<T, R>:       函数型接口,内有抽象方法—R apply(T t)
Predicate:            断言型接口,内有抽象方法—boolean test(T t)
Runnable               无参数调用执行
反射
//通过反射调用方法
Class cls = Class.forName("com.rbc.Student");
Object obj = cls.newInstance();
Method method = cls.getMethod("hello");
method.invoke(obj);

//获取字节码信息的四种形式(获取的字节码都会相等)
//方式1:通过getClass()方法获取
Person p = new Person();
Class c1 = p.getClass();

//方式2:通过内置class属性:
Class c2 = Person.class;

//方式3:--》用的最多:调用Class类提供的静态方法forName
Class c3 = Class.forName("com.zhaoss.test02.Person");

//方式4:利用类的加载器(了解技能点)
 ClassLoader loader = Test.class.getClassLoader();
Class c4 = loader.loadClass("com.zhaoss.test02.Person");

//通过字节码信息可以获取构造器:
Constructor[] c1 = cls.getConstructors(); //只能获取当前运行时类的被public修饰的构造器
Constructor[] c2 = cls.getDeclaredConstructors();//获取运行时类的全部修饰符的构造器

Constructor con1 = cls.getConstructor(); 得到无参构造器
Constructor con2 = cls.getConstructor(double.class, double.class);//得到指定的两个参数的有参构造器:
Constructor con3 = cls.getDeclaredConstructor(int.class);//得到一个参数的有参构造器:并且是private修饰的

//构造器创建对象
Object o1 = con1.newInstance(); //无参构造器创建对象
Object o2 = con2.newInstance(180.5, 170.6);//指定参数构造器创建对象

//获取属性:
Field[] fields = cls.getFields();//获取运行时类和父类中被public修饰的属性
Field[] declaredFields = cls.getDeclaredFields();//获取运行时类中的所有属性

//获取指定名字的属性:
Field score = cls.getField("score");
Field sno = cls.getDeclaredField("sno");

//属性的具体结构:
//获取属性修饰符
String s = Modifier.toString(sno.getModifiers());
//获取属性的数据类型:
Class clazz = sno.getType();
String typeName = clazz.getName();

//获取属性的名字:
String name = sno.getName();

//给属性赋值:(给属性设置值,必须要有对象)
Field sco = cls.getField("score");
Object obj = cls.newInstance();
sco.set(obj,98);//给obj这个对象的score属性设置具体的值,这个值为98

//获取方法:
Method[] methods = cls.getMethods();//获取运行时类的方法还有所有父类中的方法(被public修饰)
Method[] declaredMethods = cls.getDeclaredMethods(); //获取运行时类中的所有方法:

//获取指定的方法:
Method showInfo1 = cls.getMethod("showInfo");
Method showInfo2 = cls.getMethod("showInfo", int.class, int.class);
Method work = cls.getDeclaredMethod("work",int.class);

//获取方法的具体结构:
//方法名字:
System.out.println(work.getName());

//修饰符:
int modifiers = work.getModifiers();
System.out.println(Modifier.toString(modifiers));

//返回值:
System.out.println(work.getReturnType());
//参数列表:
Class[] parameterTypes = work.getParameterTypes();

//获取注解:
Method myMethod = cls.getMethod("myMethod");
Annotation[] annotations = myMethod.getAnnotations();

//获取异常:
Class[] exceptionTypes = myMethod.getExceptionTypes();

//调用方法:
Object o = cls.newInstance();
myMethod.invoke(o);//调用o对象的mymethod方法
showInfo2.invoke(o,12,45)

//获取运行时类的接口:
Class[] interfaces = cls.getInterfaces();

//得到父类的接口:
//先得到父类的字节码信息:
Class superclass = cls.getSuperclass();

//得到接口:
Class[] interfaces1 = superclass.getInterfaces();

//获取运行时类所在的包:
Package aPackage = cls.getPackage();
System.out.println(aPackage);
System.out.println(aPackage.getName());

//获取运行类的注解:
Annotation[] annotations = cls.getAnnotations();

//【1】问题1:创建Person的对象,以后用new Person()创建,还是用反射创建? 
正常使用new创建对象,仅在某些地方使用反射会比较方面的统一处理创建对象

//【2】问题2:反射是否破坏了面向对象的封装性? 
虽然提供了反射,并不一定非要使用,仅在某些特定场合使用
RPC调用
//客户端
public static void main(String[] args) throws Exception {
    //TCP的网络连接
    Socket socket = new Socket("127.0.0.1",8888);
    //发送请求
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());

    Class clazz = IUserService.class;
    Method method = clazz.getMethod("findUserByID", Integer.class);
    String methodName= method.getName();//方法
    Class[] parametersTypes = method.getParameterTypes();//参数类型
    Object[] params={1};

    //格式(0: 类名 1:方法名、2、方法参数类型  3、参数值)
    objectOutputStream.writeUTF(clazz.getName());
    objectOutputStream.writeUTF(methodName);
    objectOutputStream.writeObject(parametersTypes);
    objectOutputStream.writeObject(params);
    objectOutputStream.flush();

    //处理响应
    ObjectInputStream dataInputStream = new ObjectInputStream(socket.getInputStream());
    Object o = dataInputStream.readObject();
    //响应端 对象不就行了
    objectOutputStream.close();
    socket.close();

    System.out.println(o);
}

//服务端
public static void main(String[] args) throws Exception {
    ServerSocket serverSocket = new ServerSocket(8888);//监听8888端口
    while (true){
        Socket socket =serverSocket.accept();//网络请求过来了,使用socket通道(没有则阻塞)
        //业务的处理
        process(socket);
        socket.close();//关闭
    }
}
private  static  void process(Socket socket) throws Exception{
    InputStream inputStream = socket.getInputStream();//客户端送过的信息
    OutputStream outputStream= socket.getOutputStream();//响应客户端
    ObjectInputStream dataInputStream = new ObjectInputStream(inputStream);
    ObjectOutputStream dataOutputStream = new ObjectOutputStream(outputStream);

    System.out.println("process");

    //格式(0: 类名 1:方法名、2、方法参数类型  3、参数值)
    String clazzName = dataInputStream.readUTF();
    String methodName = dataInputStream.readUTF();
    Class[] parametersTypes =(Class[]) dataInputStream.readObject();
    Object[] args=(Object[]) dataInputStream.readObject();

    //通过反射去调用
    //这里一般会从服务的注册表中去找(RPC框架中, 服务的注册中心)
    Class  clazz = UserServiceImpl.class;
    Method method =  clazz.getMethod(methodName,parametersTypes);

    User user = (User)method.invoke(clazz.newInstance(),args);//通过反射调用
    dataOutputStream.writeObject(user);//这里就需要根据不同的类,
    dataOutputStream.flush();//刷新缓冲区
}
LocalDate
创建LocalDate
LocalDate localDate = LocalDate.now();
localDate.plus--
localDate.minus--

创建LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
localDateTime.plus--
localDateTime.minus--

LocalDateTime转Date
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant);

LocalDate转Date
Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant);

Date转LocalDateTime
LocalDateTime ldt = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
图片的合成
public class ImageTest {
    public static void main(String[] args) throws IOException {
         URL url = new URL("");  
         HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();  
        // 背影图片
        BufferedImage bg= ImageIO.read(new File("D://a.png"));//获取北京图片
        // 二维码图片
        BufferedImage qrCode= ImageIO.read(httpURLConnection.getInputStream());

        Graphics2D graphics2d=bg.createGraphics();
        int width= qrCode.getWidth()/3;
        int height= qrCode.getWidth()/3;
        graphics2d.drawImage(qrCode, (bg.getWidth()- width*4/3), (bg.getHeight()-height*4/3), width, height, null);
        graphics2d.dispose();
        bg.flush();
        qrCode.flush();
        ImageIO.write(bg,"png"new File("D://f.png"));
    }
}
动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
//动态代理的使用,体会反射是动态语言的关键
interface Subject {
   void action();
}
// 被代理类
class RealSubject implements Subject {
   publicvoid action() {
      System.out.println("我是被代理类,记得要执行我哦!么么~~");
   }
}
class MyInvocationHandler implements InvocationHandler {
   private Object obj;// 实现了接口的被代理类的对象的声明
   // ①给被代理的对象实例化②返回一个代理类的对象
   public Object blind(Object obj) {
      this.obj = obj;
      return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
            .getClass().getInterfaces(), this);
   }
   //当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下的invoke方法的调用
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      //method方法的返回值时returnVal
      Object returnVal = method.invoke(obj, args);
      return returnVal;
   }
}
publicclass TestProxy {
   public static void main(String[] args) {
      //1.被代理类的对象
      RealSubject real = new RealSubject();
      //2.创建一个实现了InvacationHandler接口的类的对象
      MyInvocationHandler handler = new MyInvocationHandler();
      //3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象。
      Object obj = handler.blind(real);
      Subject sub = (Subject)obj;//此时sub就是代理类的对象
      sub.action();//转到对InvacationHandler接口的实现类的invoke()方法的调用
   }
}
注解
@Target: 约束注解的使用范围,可以设置多个
TYPE, 只能注解类,接口
FIELD,  只能注解成员变量
METHOD,  只能注解成员方法
PARAMETER,  只能注解方法参数
CONSTRUCTOR,  只能注解构造器
LOCAL_VARIABLE,  只能注解局部变量

@Retention 约束注解的保留阶段
SOURCE: 注解只作用在源码阶段,生成的字节码文件中不存在
CLASS:  注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值
RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段(常用)

@Inherited 标记这个注解可被继承,某个类有该注解,则其子类也具有了该注解

@Documented 是否在生成的JavaDoc文档中体现

@Repeatable 是否可以重复标注

示例
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface AnnotationDef {
    String value() default "";
}
枚举
public enum Color {
    RED, GREEN, BLUE;
}

public enum EnumType {
    add(1), update(2);
    int type;
    EnumType(int type) {
        this.type = type;
    }
    public static EnumType getType(int type) {
        for (EnumType enumType : EnumType.values()) {
            if (enumType.type == type) {
                return enumType;
            }
        }
        return null;
    }
}
类加载器
// 获取类所在的路径信息
URL url = this.class.getResource("");

// 获取resource路径信息
URL url = this.class.getResource("/");

// 获取resource路径信息
URL url = this.class.getClassLoader().getResource("");

// 获取resource路径信息,但结果为null,需要不加'/'
URL url = this.class.getClassLoader().getResource("/");

// 外部jar包在项目resources目录下时,实例化类
URL url = this.class.getClassLoader().getResource("lib/*.jar");
URLClassLoader loader = new URLClassLoader(new URL[]{url});
Driver driver = (Driver)Class.forName("com.mysqljdbc.Driver", true, loader).newInstance();

// 外部jar包和部署项目同级目录时,实例化类
String jarDir = System.getProperty("user.dir") +"/lib/*.jar");
URL url = new File(jarDir).toURI().toURL();
URLClassLoader loader = new URLClassLoader(new URL[]{url});
Driver driver = (Driver)Class.forName("com.mysqljdbc.Driver", true, loader).newInstance();

// 实例化类获取当前项目路径
System.getProperty("user.dir")
posted @   rbcd  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示