Java源程序(.java)首先编译成与平台无关的字节码文件(.class),然后字节码文件再解释成机器码运行,解释是通过Java虚拟机来执行的。字节码文件不面向任何具体平台,只面向虚拟机,不同平台的虚拟机是不同的,但它们都提供了相同的接口,Java语言具有一次编译,到处运行的特点,就是说编译后的.class可以跨平台运行,前提是该平台具有相应的Java虚拟机。
JVM:Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的字节码文件,这种字节码文件在虚拟机上执行。JVM对上层的Java源文件是不关心的,它关注的只是由源文件生成的字节码文件(.class文件)
JRE:JRE是java runtime environment(java运行环境)的缩写。光有JVM还不能让class文件执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。
JDK:JDK是java development kit(java开发工具包)的缩写
三者之间的关系:
jdk是JAVA程序开发时用的开发工具包,其内部也有运行环境JRE。JRE是JAVA程序运行时需要的运行环境,就是说如果你光是运行JAVA程序而不是去搞开发的话,只安装JRE就能运行已经存在的JAVA程序了。JDk、JRE内部都包含JVM,JAVA虚拟机内部包含许多应用程序的类的解释器和类加载器等等。
https://blog.csdn.net/cd546566850/article/details/105353791
1、String对象是不可变的,创建了就不能更改,StringBuilder和StringBuffer是可更改的
2、StringBuilder是线程不安全的,StringBuffer是线程安全的
3、运算速度:StringBuilder>StringBuffer>String
使用场合:
返回值 | 方法 | 含义 |
---|---|---|
boolean | equals(Object object) | 比较两个字符串是否相等 |
boolean | equalsIgnoreCase(String str) | 比较两个字符串是否相等,忽略大小写 |
int | length() | 返回此字符串的长度 |
String | concat (String str) | 将指定的字符串连接到该字符串的末尾 |
char | charAt (int index) | 返回指定索引处的 char值 |
int | indexOf (String str) | 返回指定子字符串第一次出现在该字符串内的索引 |
String | substring (int beginIndex) | 返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。 |
String | substring (int beginIndex, int endIndex) | 返回一个子字符串,从beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。 (含左不含右) |
char[] | toCharArray () | 将字符串转换为一个字符数组 |
String[] | split(String regex) | 将此字符串按照给定的regex(规则)拆分为字符串数组 |
其余的方法见API文档
// char[] toCharArray():把字符串转换为字符数组
String s = "abcde";
char[] chs = s.toCharArray();
//split(String regex)
String s = "aa|bb|cc";
String[] strArray = s.split("|"); // ["aa","bb","cc"]
数组概念: 数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致
1、方式一
数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度]
int[] arr = new int[3];
2、方式二
数据类型[] 数组名 = new 数据类型[]{
元素1,元素2,元素3...}
int[] arr = new int[]{
1,2,3,4,5};
3、方式三
数据类型[] 数组名 = {
元素1,元素2,元素3...}
int[] arr = {
1,2,3,4,5};
1、访问成员变量
this.成员变量 ‐‐ 本类的
super.成员变量 ‐‐ 父类的
2、访问成员方法
this.成员方法名() ‐‐ 本类的
super.成员方法名() ‐‐ 父类的
3、访问构造方法
this(...) ‐‐ 本类的构造方法
super(...) ‐‐ 父类的构造方法
子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。
super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。
内部类:将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类
成员内部类 :定义在类中方法外的类
定义格式:
class 外部类 {
class 内部类{
}
}
访问特点:
1、内部类可以直接访问外部类的成员,包括私有成员
2、外部类要访问内部类的成员,必须要建立内部类的对象
创建内部类对象格式:
内部类名 对象名 = new 外部类型().new 内部类型();
/**
* 成员内部类
*/
public class MemberInnerClass {
private String name = "张三";
private int age = 20;
public class InnerClass{
String name = "李四";
public void show(){
System.out.println("外部类的姓名:"+MemberInnerClass.this.name);
System.out.println("内部类的姓名:"+name);
System.out.println(age);
}
}
public static void main(String[] args) {
InnerClass innerClass = new MemberInnerClass().new InnerClass();
innerClass.show();
}
}
内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名
和 符 号 。 比 如 , M e m b e r I n n e r C l a s s 符号 。 比如,MemberInnerClass 符号。比如,MemberInnerClassInnerClass.class
创建内部类对象的格式:
内部类名 对象名 = new 内部类名();
/**
* 静态内部类
*/
public class StaticInnerClass {
private static String name = "张三";
private static int age = 20;
public static class InnerClass{
String name = "李四";
public void show(){
System.out.println("外部类的姓名:"+StaticInnerClass.name);
System.out.println("内部类的姓名:"+name);
System.out.println(StaticInnerClass.age);
}
}
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
innerClass.show();
}
}
匿名内部类 :是内部类的简化写法。它的本质是一个带具体实现的父类或者父接口的匿名的子类对象。
**前提:**匿名内部类必须继承一个父类或者实现一个父接口。
格式 :
new 父类名或者接口名(){
// 方法重写
@Override
public void method() {
// 执行语句
}
};
//接口
public interface Animal {
void voice();
}
/**
* 匿名内部类
*/
public class AnonInnerClass {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
public void voice() {
System.out.println("汪汪汪");
}
};
animal.voice();
}
}
如果当方法里面的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递
public class AnonInnerClass {
public static void main(String[] args) {
showVoice(new Animal() {
@Override
public void voice() {
System.out.println("汪汪汪");
}
});
}
public static void showVoice(Animal animal){
animal.voice();
}
}
java.lang.Object
类是Java语言中的根类,即所有类的父类。它所包含的所有方法子类都可以使用。在对象实例化的时候,最终找的父类就是Object。如果一个类没有特别指定父类, 那么默认则继承自Object类
返回值 | 方法 | 含义 |
---|---|---|
boolean | equals(Object obj) | 判断其他某个对象是否与此对象“相等” |
String | toString() | 返回该对象的字符串表示 |
Class> | getClass() | 获取Class对象 |
int | hashCode() | 返回对象的哈希值 |
void | wait() | 让当前线程无线等待 |
void | notify() | 唤醒当前线程 |
void | notifyAll() | 唤醒所有在等待的线程 |
Object类的equals()方法源码:
public boolean equals(Object obj) {
return (this == obj);
}
由上可知:在没有重写equals方法时,Object类中默认进行 ==
运算符的对象地址比较,只要不是同一个对象,结果必然为false。
重写后:
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object o) {
// 如果对象地址一样,则认为相同
if (this == o)
return true;
// 如果参数为空,或者类型信息不一样,则认为不同
if (o == null || getClass() != o.getClass())
return false;
// 转换为当前类型
Person person = (Person) o;
// 要求基本类型相等,并且将引用类型交给java.util.Objects类的equals静态方法取用结果
return age == person.age && Objects.equals(name, person.name);
}
}
注意事项:equals与==的区别
上面在重写equals方法时,用到了Objects工具类。Objects工具类在JDK1.7添加进来的,它提供了一些方法来操作对象,它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),常见的方法如下:
public final class Objects {
//优化的比较两个对象的方法,可以避免出现空指针异常
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
//获取hashCode
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
//返回对象的字符串表示形式
public static String toString(Object o) {
return String.valueOf(o);
}
//比较两个对象
public static <T> int compare(T a, T b, Comparator<? super T> c) {
return (a == b) ? 0 : c.compare(a, b);
}
}
toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值
由于toString方法返回的结果是内存地址,所以在实际开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此需要重写它。
Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本类型对应的包装类,8种基本类型对应的包装类如下:
基本类型 | 对应的包装类(位于java.lang包中) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
基本类型与对应的包装类对象之间,来回转换的过程称为”装箱“与”拆箱“:
以Integer 和 int 为例,其他的同理:
基本数值---->包装对象
Integer i = new Integer(4);
Integer iii = Integer.valueOf(4);//使用包装类中的valueOf方法
包装对象---->基本数值
int num = i.intValue();
包装类常见方法:
返回值 | 方法 | 含义 |
---|---|---|
Integer | valueOf(int i) | 返回一个包装类对象 |
int | intValue(Integer i) | 将 Integer对象转换为int |
由于我们经常要做基本类型与包装类之间的转换,从Java 5(JDK 1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。例如:
Integer i = 4;//自动装箱。相当于Integer i = Integer.valueOf(4);
i = i + 5;//等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5;
//加法运算完成后,再次装箱,把基本数值转成对象。
基本类型转字符串常见的有三种方式:
/**
* 基本类型转成字符串
* 1.加一个""(空字符串)
* 2.String类的valueOf方法
* 3.包装类对象的toString方法
*/
public class BaseTypeToString {
public static void main(String[] args) {
//1.加一个""(空字符串)
String str1 = 1 + "";
System.out.println(str1.getClass());
//2.String类的valueOf方法
String str2 = String.valueOf(2);
System.out.println(str2.getClass());
//包装类对象的toString方法
String str3 = Integer.valueOf(3).toString();
System.out.println(str3.getClass());
}
}
**
* 使用包装类的parseXXX方法
*/
public class StringToBaseType {
public static void main(String[] args) {
int i = Integer.parseInt("123");
System.out.println(i);
}
}
System类中提供了大量的静态方法,可以获取与系统相关的信息或系统级操作,常见的方法:
返回值 | 方法 | 含义 |
---|---|---|
long | currentTimeMills() | 获取当前时间毫秒值 |
void | arrayCopy(Object src, int srcPos, Object dest, int destPos, int length) | 将数组中指定的数据拷贝到另一个数组中 |
public class SystemDemo {
public static void main(String[] args) {
//获取当前时间毫秒值
System.out.println(System.currentTimeMillis());
}
}
数组的拷贝动作是系统级的,性能很高。System.arraycopy方法具有5个参数,含义分别为:
参数序号 | 参数名称 | 参数类型 | 参数含义 |
---|---|---|---|
1 | src | Object | 源数组 |
2 | srcPos | int | 源数组索引起始位置 |
3 | dest | Object | 目标数组 |
4 | destPos | int | 目标数组索引起始位置 |
5 | length | int | 复制元素个数 |
//将src数组中前3个元素,复制到dest数组的前3个位置上
public class SystemArrayCopyDemo {
public static void main(String[] args) {
int[] src = new int[]{
1,2,3,4,5};
int[] dest = new int[]{
6,7,8,9,10};
System.arraycopy( src, 0, dest, 0, 3);
/*代码运行后:两个数组中的元素发生了变化
src数组元素[1,2,3,4,5]
dest数组元素[1,2,3,9,10]
*/
}
}
Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。类似这样的工具
类,其所有方法均为静态方法,并且不会创建对象,调用起来非常简单。
常见的方法(以double为例):
返回值 | 方法 | 含义 |
---|---|---|
double | abs(double a) | 返回double值的绝对值 |
double | max(double a, double b) | 取a, b中的最大值 |
double | min(double a, double b) | 取a, b中的最小值 |
double | ceil(double a) | 不小于a的最小整数 |
double | floor(double a) | 不大于a的最大整数 |
long | round(double a) | 返回最接近参数的 long(相当于四舍五入方法) |
double | pow(double a,double b) | 取a得b次方 |
double | sqrt(double a) | 取a的平方根 |
double | randow() | 产生一个随机数,double类型,范围在[ 0.0,1.0 ) |
Randow类的实例用于生成伪随机数。
public static void main(String[] args){
Random random = new Random();
//nextInt(int a) 随机产生一个范围在0~a之间的整数,含0不含a(含左不含右)
int i = random.nextInt(10);
System.out.println(i);
}
//Scanner类常用于输入数据
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
Arrays 类包含用来操作数组的各种方法,比如排序和搜索等。其所有方法均为静态方法
常用方法:
返回值 | 方法 | 含义 |
---|---|---|
String | toString(int[] arr) | 返回指定数组内容的字符串表示形式 |
void | sort(int[] arr) | 对指定的 int 型数组按数字升序进行排序 |