1. java共有类文件名必须与类名相同
java源代码文件名错了,应该与声明的class类一致,将hello.java改为Hello.java就可以了。但如果声明的class非public则文件名无需与类名相同。
一个java文件中只能有一个public类 如果想要在一个java文件中建立两个类
- 建立非 public class 也就是私有的
- 在public class内部建立 public class
java的顶级类只有public 与 default两种修饰:
- 对于顶级类(外部类)来说,只有两种修饰符:public和默认(default)。因为外部类的上一单元是包,所以外部类只有两个作用域:同包,任何位置。因此,只需要两种控制权限:包控制权限和公开访问权限,也就对应两种控制修饰符:public和默认(default)。
- 类使用了private修饰符,说明是个内部类。内部类的上一级是外部类,那么对应的有四种访问控制修饰符:本类(private),同包(default),父子类(protected),任何位置(public)。
当一个内部类使用了private修饰后,只能在该类的外部类内部使用。
2. Java数据类型
java中包含一个byte 整数类型, char是两字节的, 布尔变量为boolean 与 C++不同
对于float类型,需要加上f后缀。
浮点数可表示的范围非常大,float类型可最大表示3.4x1038,而double类型可最大表示1.79x10308。
boolean:
Java语言对布尔类型的存储并没有做规定,因为理论上存储布尔类型只需要1 bit,但是通常JVM内部会把boolean表示为4字节整数。
char
字符类型char表示一个字符。Java的char类型除了可表示标准的ASCII外,还可以表示一个Unicode字符 !!! 这点很棒了,解决了C++的问题
除了以上所说都是其他类型都是引用类型
例如:
String:
String a = “hello”;
\u之后结数字表示 Unicode字符 String 有.format操作
public static void main(String[] args) {
// 请将下面一组int值视为字符的Unicode码,把它们拼成一个字符串:
int a = 72;
int b = 105;
int c = 65281;
// FIXME:
String s= String.format("\u%04x",a) + String.format("\u%04x",b) + String.format("\u%04x",c);
System.out.println(s);
}
定义变量的时候,如果加上final修饰符,这个变量就变成了常量:
C++中是const
final double PI = 3.14;
运算符
^ 异或运算 二进制位两数不同则为1 相同为 0
3Java数组
1. java.util.Arrays
注意这里的java.util.Arrays包含对数组的操作,Array.sort 对数组进行了排序,Arrays.toString 可以将数组直接输出
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
Arrays.sort(ns);
System.out.println(Arrays.toString(ns));
}
}
2. 数组的拷贝
由于java数组是引用类型,因而直接用=的方法赋值会共享内存,所有要选择其他方式对java数组进行拷贝
4.Java 继承
instanceof
instanceof 实际上判断一个变量所指向的实例是否是指定类型,或者这个类型的子类。如果一个引用变量为null,那么对任何instanceof的判断都为false。
利用instanceof,在向下转型前可以先判断:
Person p = new Student();
if (p instanceof Student) {
// 只有判断成功才会向下转型:
Student s = (Student) p; // 一定会成功
}
只有在p是Student的子类或者本身时转化才会成功 instanceof才会返回true
jdk14之后可以不用 Student s = (Student) p这样再强制转化
直接 obj instanceof String s 即可
public class Main {
public static void main(String[] args) {
Object obj = "hello";
if (obj instanceof String s) {
// 可以直接使用变量s:
System.out.println(s.toUpperCase());
}
}
}
关键字用法:
abstract class Person
抽象类 public abstract void run() (abstract == virtual)
@Override 继承 注意O大写
继承
class Student extends Person (==C++中 class Student extends (Person))
接口
interface 关键字
接口定义的所有方法默认都是public abstract的
interface Person {
void run();
String getName();
}
当一个具体的class去实现一个interface时,需要使用implements关键字
接口也是可以继承接口的
interface Hello {
void hello();
}
interface Person extends Hello {
void run();
String getName();
}
接口中的default方法
实现类可以不必覆写default方法。
default方法的目的是,当我们需要给接口新增一个方法时,会涉及到修改全部子类。
如果新增的是default方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法。
interface Person {
String getName();
default void run() {
System.out.println(getName() + " run");
}
}
接口的静态字段
因为interface是一个纯抽象类,所以它不能定义实例字段。但是,interface是可以有静态字段的,并且静态字段必须为final类型:
public interface Person {
// 编译器会自动加上public statc final:
int MALE = 1;
int FEMALE = 2;
}
5.包
java类引用其他的类
Java编译器最终编译出的.class文件只使用完整类名,因此,在代码中,当编译器遇到一个class名称时:
-
如果是完整类名,就直接根据完整类名查找这个class;
-
如果是简单类名,按下面的顺序依次查找:
查找当前package是否存在这个class;
查找import的包是否包含这个class;
查找java.lang包是否包含这个class。
编写class的时候,编译器会自动帮我们做两个import动作:
默认自动import当前package的其他class;
默认自动import java.lang.*。
注意:自动导入的是java.lang包,但类似java.lang.reflect这些包仍需要手动导入。
final 修饰符的作用
- 用final修饰class可以阻止被继承:
package abc;
// 无法被继承:
public final class Hello {
private int n = 0;
protected void hi(int t) {
long i = t;
}
}
- 用final修饰method可以阻止被子类覆写:
package abc;
public class Hello {
// 无法被覆写:
protected final void hi() {
}
}
- 用final修饰field可以阻止被重新赋值:
package abc;
public class Hello {
private final int n = 0;
protected void hi() {
this.n = 1; // error!
}
}
- 用final修饰局部变量可以阻止被重新赋值:
package abc;
public class Hello {
protected void hi(final int t) {
t = 1; // error!
}
}
6. 包装类型
基本知识点
将基本类型包装成引用类型
使用方法:
主要有 new直接创建以及Long.valueOf() 这两个方式
new不推荐使用 占用内存大且不易优化
输出包装类中的值可以使用 n.*Value() ;
public class Main {
public static void main(String[] args) {
long i = 100;
// 通过new操作符创建Integer实例(不推荐使用,会有编译警告):
Long n1 = new Long(i);
// 通过静态方法valueOf(int)创建Integer实例:
Long n2 = Long.valueOf(i);
// 通过静态方法valueOf(String)创建Integer实例:
Long n3 = Long.valueOf("100");
System.out.println(n3.longValue());
}
}
自动装箱与拆箱操作
不建议常用
装箱和拆箱会影响代码的执行效率,因为编译后的class代码是严格区分基本类型和引用类型的。并且,自动拆箱执行时可能会报NullPointerException(因为引用类型可以赋值为null但是基本类型不可以)
Integer n = 100; // 编译器自动使用Integer.valueOf(int)
int x = n; // 编译器自动使用Integer.intValue()
比较运算
比较时不能使用==直接比较,必须用equals()方法比较两个Integer
x.equals(y);
进制转换
parseInt()可以把字符串解析成一个整数:
int x1 = Integer.parseInt("100"); // 100
int x2 = Integer.parseInt("100", 16); // 256,因为按16进制解析
Integer还可以把整数格式化为指定进制的字符串
Integer.toString(100); // "100",表示为10进制
Integer.toString(100, 36); // "2s",表示为36进制
Integer.toHexString(100); // "64",表示为16进制
Integer.toOctalString(100); // "144",表示为8进制
Integer.toBinaryString(100); // "1100100",表示为2进制
7.JavaBean
通过函数的命名规范来获取类内信息
public Type getXyx()
public void setXyx(Type name)
public class Main {
public static void main(String[] args) throws Exception {
BeanInfo info = Introspector.getBeanInfo(Person.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
System.out.println(pd.getName());
System.out.println(" " + pd.getReadMethod());
System.out.println(" " + pd.getWriteMethod());
}
}
}
class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
输出:
age8.
public int Person.getAge()
public void Person.setAge(int)
class
public final native java.lang.Class java.lang.Object.getClass()
null
name
public java.lang.String Person.getName()
public void Person.setName(java.lang.String)
8.Java enmu类型
在java中有一个非常强大的类型叫enmu 它可以很方便的帮助我们解决一些需要枚举的操作
- 定义的enum类型总是继承自java.lang.Enum,且无法被继承
- 只能定义出enum的实例,而无法通过new操作符创建enum的实例;
- 定义的每个实例都是引用类型的唯一实例;
我们直接定义:
public enum Color {
RED, GREEN, BLUE;
}
编译器为每个变量创建实例:
public final class Color extends Enum { // 继承自Enum,标记为final class
// 每个实例均为全局唯一:
public static final Color RED = new Color();
public static final Color GREEN = new Color();
public static final Color BLUE = new Color();
// private构造方法,确保外部无法调用new操作符:
private Color() {}
}
name()
返回常量名,例如:
String s = Weekday.SUN.name();
ordinal()
返回定义的常量的顺序,从0开始计数,例如:
int n = Weekday.MON.ordinal(); // 1
9 java BigInteger
- 所在库 import java.math.BigInteger;
- 进行运算是需要使用实例方法 i1.add(i2)
- 转化成基本数据类型
转换为byte:byteValue()
转换为short:shortValue()
转换为int:intValue()
转换为long:longValue()
转换为float:floatValue()
转换为double:doubleValue() - 为了防止超出范围可以使用 intValueExact()、longValueExact()等方法
10 java 异常
final 保证最后一条一定可以正确执行
void process(String file) throws IOException {
try {
…
} finally {
System.out.println(“END”);
}
}
多级异常
在finally中有异常的话会先只抛出finally中的异常
可以用如下方法使得异常全部抛出
Exception origin = null;
e.addSuppressed(origin);
public class Main {
public static void main(String[] args) throws Exception {
Exception origin = null;
try {
System.out.println(Integer.parseInt("abc"));
} catch (Exception e) {
origin = e;
throw e;
} finally {
Exception e = new IllegalArgumentException();
if (origin != null) {
e.addSuppressed(origin);
}
throw e;
}
}
}