前言:有地基才能有高楼大厦
java是一门强类型的语言
1.1 什么叫强类型什么叫弱类型呢?
强类型:
强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例子:如果你定义了一个整形变量 a,那么程序根本不可能将 a 当作字符串类型处理。强类型定义语言是类型安全的语言。
弱类型
数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。
强类型定义语言在速度上可能略逊色于弱类型定义语言,但是强类型定义语言带来的严谨性能够有效的避免许多错误。例如:JavaScript
1.2 强类型和弱类型各有什么优势?
java是静态语言
2.1 什么叫静态语言什么叫动态语言?
静态语言
(1)变量的类型在编译的时候确定
(2)变量的类型在运行时不能修改
(3)这样编译器就可以确定运行时需要的内存总量
动态语言
(1)变量的类型在运行的时候确定
(2)变量的类型在运行可以修改
java是跨平台的语言
一套代码跑各个平台
java是面向过程的语言
4.1 面向过程和面向对象的优缺点
byte short char int float double long boolean

注意:整形默认为int,如果数值不属于int范围,会报错,整形后面加L代表是long数据。浮点型显性默认为double,浮点数高精度类型不能直接赋值给低精度类型,会造成精度损失,编译不通过,必须加F,加F代表是float数据
例如:
long value = 9223372036854775807; //错误写法
long value = 9223372036854775807L; //正确写法相等于long value = (long)9223372036854775807L;
float f = 1000.1; // 错误写法编译不通过
float f = 1000.1F; // 正确写法相等于 float f = (float)1000.1;
所有的非基本数据类型都是引用数据类型


// 基础类型转成包装类
Long l = new Long(1000L);
Long l2 = Long.valueOf(100L); // 包装类.valueOf(基本数据类型变量)
// 包装类转成基本类型
long basicL = l.longValue(); // 包装类变量.基本数据类型value()
Integer i = 10; //装箱 相当于Integer i = Integer.valueOf(10)
int n = i; //拆箱 相当于int n = i.intValue()
对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,是同一个对象则为true,如果不在这区间,则为false
Integer i = 100;
Integer j = 100;
System.out.print(i == j); //true
Integer i = 128;
Integer j = 128;
System.out.print(i == j); //false
答案在源码中很容易找到,装箱是调用的valueOf方法,源码如下
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
我们看到如果是在IntegerCache.low和IntegerCache.high之间,都是返回的同一个对象,这些对象在加载类的时候就已经创建好了
注意:Float,Double并没有实现常量池技术。
| 名称 | 中文简称 | 类内部是否可以访问 | 同包是否可以访问 | 不同包是否可以访问 | 子类是否可以访问 |
|---|---|---|---|---|---|
| privalte | 私有的 | 可以 | 不可以 | 不可以 | 不可以 |
| default | 默认不写 | 可以 | 可以 | 不可以 | 不可以 |
| protected | 受保护的 | 可以 | 可以 | 不可以 | 可以 |
| public | 公开的 | 可以 | 可以 | 可以 | 可以 |

static静态、可以修饰属性,方法,还可以定义代码块,被修饰的元素隶属于类,被类的所有对象共享。

顶层类 Throwable 派生出两个重要的子类, Error 和 Exception
Error:Error的错误是致命的,一但发生Error JVM就会停止
Exeption:Exeption不会停止JVM。
异常又分为,运行时异常,和编译异常
try-catch-finaly(捕获)
try (如果有资源需要在代码块执行完释放可以把变量声明在这里,前提是资源要实现AutoCloseable接口) {
// 可能发生异常的代码
} catch (Exception e ) {
// 发生异常处理的代码
} finally {
// 不管发不发生异常都会执行的代码块
}
注意点:
如果catch里面有return,return语句会在finally代码块的最后执行
catch可以有多个
throw throws (抛出异常,交给上层处理)
throw主动抛出异常
if () { throw new NumberFormatException("主动抛出") }throws 定义可能会发生的异常
public Integer test() throws NumberFormatException() { }
在我们日常开发中,大部分异常是够用的,但是又些时候需要我们自己去继承RuntimeExecption类定义一个自己的异常来满足需求

逻辑运算符:先走一遍,在判断&、|、^、!短路逻辑运算符:一但符合条件,后面的判断不走&&、||泛型不支持基本数据类型,用包装类代替
为什么要使用泛型?
保证了类型的安全性。
消除强制转换
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);
// 使用泛型
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0); // no cast
泛型通配符:
重载:方法名称都相同,方法参数顺序、参数类型、参数个数不一样
重写:只有继承才会有重写,方法名称,方法参数顺序、参数类型、参数个数都一致。重写的访问修饰符必须大于等于父类
abstract类:天生就是为了规范来被子类继承的,不能被实例化,不能用final修饰(因为可以abstract类就是要用来继承的),与接口不同的是,abstract可以有普通成员变量、方法。
abstract方法:abstract方法必须存在abstract类中,不能用private、static修饰(因为子类必须要重写),abstract方法必须被重写
接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。interface只能用在类上,接口中的所有方法都是abstract的,子类必须重写。
interface是强调实现功能可以多实现,interface里面的方法都是abstract的,实现的子类全部要重写,没有构造器
abstract是强调所属关系只能单继承,abstract类可以存在非abstract的方法,子类可以选择是否要重写、有构造器
关键字extends,我们可以让一个类和另一个类建立起父子关系.例如
// Student称为子类(派生类),People称为父类(基类或超类)
// 当子类继承父类后,就可以直接使用父类公共的属性和方法了
public class Student extends People {}
注意:
final 的方法子类不可重写
private default 方法、属性、子类不可访问
this:是自身的一个对象,代表对象本身
super:可以理解为是指向自己超(父)类对象,这个超类指的是离自己最近的一个父类
implements用来实现接口,可以多实现,以逗号分割
实现多态的条件
例如:
public class Duo {
public void test () {
System.out.println("Duo");
}
}
public class Duo2 extends Duo {
@Override
public void test() {
System.out.println("Duo2");
}
}
public class Demo {
public static void main(String[] args) {
Duo duo = new Duo2();
duo.test(); // 输出 Duo2
Duo duo = new Duo();
duo.test(); // 输出 Duo
}
}
String不是基本数据类型,它在内部存储了一个 final char数组

String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了,如果需要对字符串做很多修改,那么应该选择使用 StringBuffer / StringBuilder

String str1 = "abc";
String str2 = "abc";
String str3 = "abc";
String str4 = new String("abc");
String str5 = new String("abc");

双引号这种方式创建String,会判断字符串常量池中,有没有这个常量,如果有的话,直接引用,如果没有创建常量
其他的创建方式会在堆里创建对象,堆再引用常量池的常量,返回堆里的引用

我们看到这是个native方法,被native修饰的方法,都是和操作系统的打交道的方法,我们看不到,不能修改
调用intern方法,会判断字符串常量池中是否用,有的话直接返回字符串常量池中的引用,如果没有就创建,返回字符串常量池的引用,证明如下:
String a = "a";
String b = new String("a");
System.out.println(a == b); // false
String c = b.intern();
System.out.println(a == c); // false
这两者相同点:可变字符串类,内部都维护了一个char[] value;,有扩容机制,capacity()方法可以返回实际的长度
这两者区别:StringBuffer内部使用synchronized 关键字进行修饰,所以是线程安全的,StringBuilder线程不安全

public class Demo {
// 成员内部类
class inner1 {}
// 静态内部类
static class inner2 {}
public void demoMethod() {
// 方法内部类
class inner3 {}
// 匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
}
});
}
}
1、成员内部类特点:
成员内部类实例需要通过外部类,如new Demo().new inner1(),成员内部类可以访问外部类的所有属性方法
2、局部内部类特点:
局部内部类:作用域只能是在方法内
3、静态内部类特点:
不依赖外部类实例,外部类.new 静态内部类()new创建对象,只能访问外部类的静态属性,可以拥有自己的成员属。通俗意思就是,定义了一个类,这个类可以访问外部类static的成员属性和方法
4、匿名内部类特点:
匿名内部类不能定义任何静态成员、方法和类,通常用来实现一个接口,访问局部变量,这个局部变量必须是final
首先看下面代码
public class Employee {
public String name=null;
public Employee(String n){
this.name=n;
}
//将两个Employee对象交换
public static void swap(Employee e1,Employee e2){
Employee temp = e1;
e1 = e2;
e2 = temp;
System.out.println(e1.name+" "+e2.name); //打印结果:李四 张三
}
public static void main(String[] args) {
Employee worker = new Employee("张三");
Employee manager = new Employee("李四");
swap(worker,manager);
System.out.println(worker.name + " " + manager.name); //打印结果仍然是: 张三 李四
}
}
通过上面的代码,发现形参上的交换,并没有改变实参,所以一定不是引用传递。实际它是地址copy,在swap方法中,我们实际上是改变了地址值,不会影响原实参的地址引用。
我们再来看看一段代码
public class Employee {
public StringBuilder name=null;
public Employee(StringBuilder n){
this.name=n;
}
//将两个Employee对象交换
public static void swap(Employee e1,Employee e2){
e1.name.append("交换");
e2.name.append("交换");
}
public static void main(String[] args) {
Employee worker = new Employee(new StringBuilder("张三"));
Employee manager = new Employee(new StringBuilder("李四"));
swap(worker,manager);
System.out.println(worker.name.toString());
System.out.println(worker.name.toString()+" "+manager.name.toString()); //张三交换 李四交换
}
}
结果是改变了实参,用通俗的话就是,相当于有形参实参参数是指向同一个地址的,打个比方就是有两把钥匙,两把钥匙都可以进入房子,备用钥匙进去,把电冰箱换成了洗衣机,然后主要钥匙再进去肯定是电冰箱换成了洗衣机。但是第一段代码的情况是这样的,有两把钥匙,备用钥匙又重新进锅炉,融化,变成了可以打开其他房子的钥匙,把其他房子的电冰箱换成了洗衣机,肯定是不会影响到主要钥匙的房子的。判断是否发生改变的核心就是看看是否发生了地址的改变。
(静态成员 -> 静态代码块) ->( 非静态成员变量 -> 非静态代码块 - > 构造方法)
++a:先自己+1,再参与运算
a++:参与运算再自己+1
我们看看++a和a++的操作数栈,上代码:
public class Demo {
public static void main(String[] args) {
int a = 1;
// 1 + 3
int b = a++ + ++a;
System.out.println(b); // 4
System.out.println(a); // 3
}
}
操作数栈:
0 iconst_1 // 入栈一个1的值
1 istore_1 // a存入局部变量表第一个位置
2 iload_1 // 加载局部变量表第一个位置到栈 a = 1
3 iinc 1 by 1 // 局部变量表第一个位置自增+1,增加前a=1,增加后a=2
6 iinc 1 by 1 // 局部变量表第一个位置自增+1,此时 a=2,再自增+1, a=3
9 iload_1 // 加载局部变量表第一个位置 a=3
10 iadd // 相加
11 istore_2 // b存入到局部变量表2的位置
12 getstatic #2 <java/lang/System.out> //打印
15 iload_2
16 invokevirtual #3 <java/io/PrintStream.println>
19 return
JDK7之前有些情况,我们需要实现一个接口作为参数传入,我们不得不,写一个类来实现接口,而这个接口我们只需要用一次,代码会变得臃肿,lambda的到来,就是为了解决这个问题。
在lamdba没有出现之前,我们想要实现一个接口只有一个方法的时候,从繁到简的演变过程:
@FunctionalInterface
public interface LambdaInterface {
void test();
}
public interface Run {
void test(LambdaInterface);
}
1、定义一个专门的类来实现
public class LamdbaImpl implements LambdaInterface {
@Override
public void test() {
}
}
public class LamdbaDemo {
public static void main(String[] args) {
Run.test(new LamdbaImpl())
}
}
2、静态成员内部类
public class LamdbaDemo {
static class LamdbaInner implements LambdaInterface {
@Override
public void test() {
}
}
public static void main(String[] args) {
Run.test(new LamdbaInner())
}
}
3、局部内部类
public class LamdbaDemo {
public static void main(String[] args) {
class LamdbaInner implements LambdaInterface {
@Override
public void test() {
}
}
Run.test(new LamdbaInner())
}
}
4、匿名内部类
public class LamdbaDemo {
public void test() {
LambdaInterface lambdaInterface = new LambdaInterface() {
@Override
public void test() {
}
};
Run.test(lambdaInterface)
}
}
5、lamdba
public class LamdbaDemo {
public void test() {
Run.test(()->{
})
}
}
使用lamdba会可以让我们的代码简洁很多,但是同时也会降低可读性,阿里巴巴开发手册中,规定了不允许用lamdba。
tips:在接口中添加了 @FunctionalInterface 的接口,只允许有一个抽象方法,否则编译器也会报错,可以拥有若干个默认方法。
注意点:lamdba内部访问外部方法内的变量必须是final的
例如:
public class LamdbaDemo {
public static void main(String[] args) {
int i = 1;
new Thread(()-> {
i++; // error
System.out.println(i);
}).start();
}
}
引用静态方法:
引用静态方法,接口 = Class名::静态方法名,如果接口的返回类型为void,静态方法的返回类型可以为任意的,如果接口的返回类型不为void,静态方法的返回类型需要和接口一致。接口和静态方法的参数类型,顺序必须一样。
public class LamdbaDemo {
public static void main(String[] args) {
// Person person = food -> {
// LamdbaDemo.eat(food);
// };
Person person = LamdbaDemo::eat;
person.eat("1");
}
static String eat(String food) {
System.out.println(food);
return food;
}
}
interface Person {
void eat(String food);
}
引用实例方法:
引用实例方法,接口 = Class名::成员方法名,如果接口的返回类型为void,成员方法的返回类型可以为任意的,如果接口的返回类型不为void,静态方法的返回类型需要和接口一致。接口和方法的参数类型,从第二开始算起,顺序必须一样,因为第一个参数是实例对象。
public class LamdbaDemo {
public static void main(String[] args) {
Person person = LamdbaDemo::eat;
person.eat(new LamdbaDemo(), "niu");
}
public String eat(String food) {
System.out.println(food);
return food;
}
}
interface Person {
void eat(LamdbaDemo lamdbaDemo, String food);
}
引用this
引用this和实例方法的区别就是,实例就是this,可以省略不写
public class LamdbaDemo {
public void test() {
Person person = this::eat;
person.eat("niu");
}
public String eat(String food) {
System.out.println(food);
return food;
}
}
interface Person {
void eat(String food);
}
stream是优化集合处理的优化,它是链式的,对于处理数据比较大的时候,效率很高,对于数据量比较小,直接使用普通的for效率比较高
Stream和Collection集合的区别:
这位老哥写的还可以,点击跳转
多个线程来处理流,将一个大任务,分而治之分成很多个线程去执行(fork/join原理)
获取并行流的方式:
通过已有的串行流获取并行流
List<Integer> integers = Arrays.asList(1,2,3,4);
Stream<Integer> stream = integers.stream();
// 通过已有的串行流获取并行流
Stream<Integer> parallel = stream.parallel();
直接获取
List<Integer> integers = Arrays.asList(1,2,3,4);
// 直接获取
Stream<Integer> stream = integers.parallelStream();
并行流的线程安全问题:
ArrayList<Integer> integers = new ArrayList<>();
// 添加一万个数据到integers
for (int i = 0; i < 10000; i++) {
integers.add(new Random().nextInt(1000));
}
ArrayList<Integer> integers2 = new ArrayList<>();
// 获取integers的并行流
integers.parallelStream().forEach(x -> {
// Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
integers2.add(x);
});
System.out.println(integers2.size());
解决方式:
Fork/Join框架是Java 7提供的一个用于并行执行任务的框架, 核心思想就是把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果
Fork/Join框架使用一个巧妙的算法来平衡线程的负载,称为工作窃取(work-stealing)算法。工作窃取的运行流程图如下:

fork join属于并发编程系列:看这篇文章,点击跳转
optional类是为了解决我们日常开发中多嵌套判断是否为null而存在的,看一个例子:
if (user != null) {
Address address = user.getAddress();
if (address != null) {
Country country = address.getCountry();
if (country != null) {
String isocode = country.getIsocode();
if (isocode != null) {
return isocode.toUpperCase();
}
}
}
}
这样的代码非常的难维护,如果我们换成Optional
首先,重构类,使其 getter 方法返回 Optional 引用:
public class User {
private Address address;
public Optional<Address> getAddress() {
return Optional.ofNullable(address);
}
// ...
}
public class Address {
private Country country;
public Optional<Country> getCountry() {
return Optional.ofNullable(country);
}
// ...
}
现在我们可以这样写
User user = new User("anna@gmail.com", "1234");
String result = Optional.ofNullable(user)
.flatMap(u -> u.getAddress())
.flatMap(a -> a.getCountry())
.map(c -> c.getIsocode())
.orElse("default");
方法:

简单来说就是。jdk7之前的日期api不健全,线程不安全,不丰富,现在新增了几个类,都是线程安全的
可以很清晰的看出ZonedDateTime相当于LocalDateTime+ZoneId

这篇文章写的很好:点击跳转
如果我们需要定义一组常量,最好是是使用枚举类
特点:可以进行排序,构造方法是私有的,不能再继承类。
方法:
文章太长了,放在我另一篇博客中了,点击跳转
待更新
待更新
待更新
目录Collection集合概述Collection集合继承结构图详细介绍Collection接口的常用方法详细介绍Collection的两个方法需要注意的问题Iterator迭代器迭代器的代码实现迭代器和remove方法冲突问题增强for循环Collection集合的子类List接口独有的常用方法ArratList集合介绍三种构造方法LinkedList集合链表的优缺点常用方法
目录前言一、运算符1.1算术运算符1.2关系运算符1.3逻辑运算符1.4位运算符1.5移位运算1.6条件运算符二、注释2.1基本规则2.2注释规范三、关键字四、顺序结构五、分支结构5.1if语句5.2switch语句六、循环结构6.1while循环6.2break6.3continue6.4for循环6.5do...while循环前言大家好~我又来了!今天给大家总结一下运算符和程序逻辑控制相关知识!让我们开始今天的学习吧!对了!给大家推荐一个刷题学习、面试神器——牛客网里面有非常多的题库,跟面试经验~非常的良心!!一、运算符1.1算术运算符基本四则运算符:+/*%这些运算符,C语言中已经讲到很
❤️❤️个人主页:摸鱼王胖嘟嘟🌟🌟作品专栏:【手把手带你学JavaSE系列】📑给大家推荐一款非常火的面试、刷题、学习神器👉牛客网👉点击注册一起刷题、学习、讨论收获大厂offer吧!目录前言一、项目需求二、实现思路三、代码实现1.book包Book类BookList类2.operations包AddOperation类BorrowOperation类DelOperation类DisplayOperation类ExitOperation类FindOperation类ReturnOperation类IOperation接口3.user包AdminUser类NormalUser类User类Main类四
🧛♂️iecne个人主页::iecne的学习日志💡每天关注iecne的作品,一起进步💪学C++必看iecne本文专栏:【JavaSE】🐳希望大家多多支持🥰一起进步呀!✨前言哈喽大家好,我是iecne,本期为大家带来的是【JavaSE】初识Java解决工具包问题详解。包教包会,快来看看吧!任务描述如何快速掌握函数,看iecne的【JavaSE】初识Java解决工具包问题详解文章目录✨前言任务描述一.初识Java1.1什么是Java1.2Java的优点👍1.3Java的软件推荐1.3.1开发工具1.3.2编译工具1.4Java语言特点1.5Java的安全性二.JDK和IDEA路劲问题三.hell
我不知道问这个问题是否合适,但我在这里问。到目前为止我尝试过的:在我所有的JavaSE(Swings、JavaFX)等项目中,我都使用MySQL、Oracle、MSSQLServer作为我的后端。但是对于其中任何一个,我都需要安装一个单独的软件,例如MySQL服务器等。我想知道是否有可能得到一些替代品,这样我就不需要为数据库安装任何额外的个人软件。数据库应该集成在我的JavaSE应用程序中,就像我们在普通软件中看到的那样。我们只是安装软件,而不是为其安装单独的DBMS。这样的数据库可以让我备份。有什么建议吗? 最佳答案 你可以使用A
我快读完“HeadFirstJava”这本书了。我研究这个的原因是我希望有一天能找到一份使用JavaEE进行开发的工作。现在我在想,我应该继续学习EE(转向HeadFirstServlets和JSP)还是应该花更多时间学习SE?这会有帮助吗?我会继续直接说我想在最快但最合适的时间(一种平衡的方式)学习EE。有什么建议吗?提前致谢! 最佳答案 对我来说,使用JavaEE很好,因为您已经充分使用了SE。当然,在编程论坛中闲逛会时不时地教给您一些仍然对您隐藏的东西。相信我会有很多。无论如何,我给你的建议很少,这将帮助你走上这条路。最好对J
我试图将Eclipse项目导入到IntelliJIDEA中,但我遇到了这个错误: 最佳答案 eclipse项目描述包含对“手动”定义的JDK(名为JavaSE-1.8)的引用。只需继续并自己在IntelliJ中为您的项目定义一个SDK。参见here必要的步骤:TodefineaJDKandamobileSDKinIntelliJIDEAOpentheProjectStructuredialog(e.g.Ctrl+Shift+Alt+S).Intheleftmostpane,underPlatformSettings,clickSDK
我使用Eclipse作为IDE,并在其外部使用Maven来使所有依赖项保持最新并更新Eclipse项目。在Eclipse中,我通常将JRE系统库指定为任何Java项目的执行环境,通常是“JavaSE-1.6”。在pom.xml中,我使用以下行:maven-compiler-plugin2.3.21.61.6maven-eclipse-plugin2.8[groupId].[artifactId]true2.0这好像是让Maven挑选一个JDK匹配1.6。它将其系统库分配给项目的类路径。但是,它直接使用jdk1.6.20而不是JavaSE-1.6。有没有办法让Maven改用JavaSE-
目录1什么是状态观测器?2Luenberger状态观测器1什么是状态观测器?为了对系统实现状态反馈,状态观测器应运而生。状态观测器是一种通过原受控系统的输入、输出量来重新构建一个与原系统相似的动态系统。它的输出信号的状态估计近似于原受控系统的状态,其差值的极限为0。基础构想如图所示。2Luenberger状态观测器当系统状态量难以获取,但实际控制中又需要利用系统状态量时,如何通过输入量和输出量重构系统状态量,这便是Luenberger状态观测器设计初衷。Luenberger状态观测器通过在系统的反馈通道上设置一个补偿器,可以获得一些不可测的信息,并产生比原系统阶数低的动态系统。Luenberg
目录前言一、字符串查找二、字符串转换2.1数值和字符串转化2.2大小写转化2.3字符串和数组的转换2.4格式化三、字符串替换四、字符串拆分4.1拆分处理4.2部分拆分4.3拆分IP地址五、字符串截取六、其他的方法6.1Stringtrim()6.2booleanisEmpty()6.3intlength()6.4判断字符串开头结尾6.5booleancontains(Stringstr)七、StringBuilder&&StirngBuffer7.2String、StringBuffer、StringBuilder的区别前言上篇我们已经学习了String类的一些知识,接下来我们接着学习!一、字