【笔记】JAVA语言学习笔记

1.对于Integer var = ?在-128至127范围内的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断

  • 但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑, 推荐使用equals方法进行判断
  • 这个-128至127会受启动参数影响的,例如-XX:AutoBoxCacheMax=20000

2.Object的cloe()方法慎用,因为做的是浅拷贝

3.基础类型和包装类型

  • 包装类型复制
    1
    Integer i = Integer.valueOf(str);
  • 包装类型转基础类型
    1
    int i = Integer.parseInt(source);

4.取绝对值

1
int target = Math.abs(source);
  • 有个例外是abs(-2^31),仍然是复数,因为转成正数后int溢出了

5.单引号代表字符,双引号代表字符串

6.集合和数组

  • 集合转数组实例
    1
    2
    3
    4
    5
    List<String> list = new ArrayList<String>(2);
    list.add("guan");
    list.add("bao");
    String[] array = new String[list.size()];
    array = list.toArray(array);
  • Arrays.asList()把数组转集合的坑
    • 原理是asList()方法返回的对象底层其实也还是Arrays数组,他只是把原数组的值处理了,并没有去修改list类型的add/get/remove方法,当调用这些方法时会去抛异常
      1
      2
      3
      4
      5
      String[] str = new String[] { "you", "wu" };
      List list = Arrays.asList(str);

      第一种情况:list.add("yangguanbao"); 运行时异常
      第二种情况:str[0]= "gujin";那么list.get(0)也会随之修改

7.Map类汇总

  • Hashtable:父类Dictionary,线程安全,k、v都不允许为null
  • ConcurrentHashMap:父类AbstractMap,线程安全(采用锁分段技术),k、v都不允许为null
  • TreeMap:父类AbstractMap,线程不安全,允许v为null
  • HashMap:父类AbstractMap,线程不安全,允许k、v为null

8.volatile的作用

  • 可见性:修饰的变量一旦修改,会立即被更新到主存,其他线程读这个变量时会优先去主存里拿值
    • 普通变量被修改后更新主存的时间不确定,所以不能保证主存里是最新值
  • 保证有序性:保证操作系统按分配内存空间->初始化对象->将内存空间的地址赋值给对应的引用,的顺序来构造新对象
  • 保证原子性:修饰基本类型的变量时,对这个变量的操作都变成原子级别
    • 唯一例外给该变量的新值与它自身的旧值有关,例如n = n + 2,解决办法是用synchronized写一个自增方法,然后去掉这个方法来实现+2
      1
      2
      3
      public static synchronized void inc(){  
      n = n + 2;
      }

9.抛出的Exception类型变量e,用以下方法打印到标准错误流中

1
e.printStackTrace()

10.java的启动不同于C++和Go使用main文件启动

  • 而是去扫描项目里的所有类,从含有main()方法的地方开始启动

11.设置系统全局变量(相当于一个静态变量,存在内存里面)

  • 设置
    1
    System.setProperty(key, val);
  • 使用
    1
    System.out.println(System.getProperty(key));

12.获取xx类的class对象

1
xx.class

13.Spring Boot

  • 自动嵌入了Tomcat,所以实际使用该框架的时候不用自己去配tomcat,本地运行后自动在127.0.0.1:8080上部署
  • Spring Boot会在初始化的时候自动去实例化每个类一个对象
    • 尽量不要去new 一个对象,因为new出来的对象可能不会去走一些初始化的方法
    • 如果在A类里面需要去调用b类里的成员,在A类里面写一个成员类B即可
      1
      2
      3
      4
      @Autowired
      B b;
      ......
      System.out.println(b.xx);

14.@RequestMapping是用来注册访问路径的

  • 例如以下程序会提供一个ip:port/demo/的接口,访问这个接口会看到”Hello World的信息”
    1
    2
    3
    4
    @RequestMapping("/demo/")
    String home() {
    return "Hello World!";
    }
  • 可以指定访问方式,没指定的话就默认所有方式都可以
    1
    @RequestMapping(value = "/demo/", method = RequestMethod.GET)
  • value的值也可以是一个字符串数组,这样访问其中一个地址就能访问该接口
    1
    @RequestMapping(value = {"/demo/", "/demo2/"}, method = RequestMethod.GET)
  • 还可以设置headers来限制访问,只有headers里面符合的才能访问
    1
    @RequestMapping(value = "/demo/", headers = "Host = localhost:8081")

15.@是Java的注解,又称标注

  • 在方法、类的上一行写上@xx,如果该方法和类没有满足的话编译器编译时会警告
    • 例如@Override,如果注解的方法没有重写父类方法的话就会警告
  • 用作初始化,可以看成是调用某个方法
  • 自定义一个注解的写法
    1
    2
    3
    4
    5
    6
    7
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Inherited
    public @interface MyS {
    String val();
    }
  • 使用自定义的注解
    1
    2
    3
    4
    public class xx {
    @MyS(val = "xxxx")
    .....
    }

16.单测语法

  • 以下表示如果x != y那么就算测试失败,这个x、y可以是任意类型,也可以是某个函数的调用结果
    1
    expect(x).toEqual

踩坑

1.The bean “xx”, defined in class path resource

  • 原因:相同名字的类在bean注入容器的时候重复了
  • 解决办法:把其中一个类的名字改一下就行了

2.程序包sun.reflect.generics.reflectiveObjects不存在

  • 原因:该类放在rt包里面,而rt包在jdk9中就被删除了
  • 解决办法:在File->Project Structure->Modules->Dependencies里面修改为jdk8即可
    • 如果仍报错,就去File->Settings->Build, Execution….->Build Tools->Maven->Runner里面把Delegate IDE build/…勾选上,这个选项会每次运行前去执行一遍maven的打包功能

3.无法ping通JMX port 1099/无法创建JVM/Unrecognized option

  • 原因:tomcat版本错误或者jdk版本错误
  • 解决办法:使用tomcat9 + jdk1.8

4.日志打印中文乱码

  • 原因:log4j导致的
  • 解决办法:Help->Edit Custom VM Options,打开的文件最后一行加上以下语句,然后再重启ide即可
    1
    -Dfile.encoding=UTF-8