object.method(parameters)
强类型:必须为每个变量声明一种类型
整型
byte
short
int
long
浮点型
float
double
(正无穷大、负无穷大、NaN)
char(2byte)
Unicode字符用一个或两个char类型表示。
使用char描述所有Unicode字符:码点(17个代码级别)
boolean
整型与boolean不能转换
变量
声明(命名)
初始化
常量
final:只能赋值一次
类常量:在类的多个方法中使用(static final)
运算符
加、减、乘、除(除零时的结果差异)、取模
浮点运算,保持移植时的精确度,使用strictfp修饰类或方法(截断操作,有可能溢出)
字符串
subString
format
不可变:效率权衡-字符串常量共享
CodePoint:一个或两个代码单元(char)构成
输入输出
输入
Scanner:关联标准输入System.in、scanner.nextLine、next()、netInt()
Console:从控制台读取密码cons.readPassword(“Password:”)
输出
System.out.printf("%8.2f", x);
System.out.printf(“Hello, %s. Next year, you’ll be %d”, name, age);
文件的IO
读取:Scanner in = new Scanner(Paths.get(“myfile.txt”), “UTF-8”);
写入:PrintWriter out = new PrintWriter('myfile.txt", “UTF-8”);
确定启动路径:String dir = System.getProperty('user.dir"):
控制流程
块作用域
条件语句
循环
while:为真才执行
dowhile: 先执行再判断,至少执行一次
for
多重选择switch语句
case标签可以为:byte、short、int、char、枚举变量、字符串字面量,注意case贯穿问题
中断控制流程
continue
带标签的break——跳出多层嵌套的控制
label:
{
// deal with bad situation
// carry out normal processing
if (condition) break label; // exits block
...
}
// jumps here when the break statement executes
静态域
也称类域,属于类,不属于任何类的对象。而实例域,每一个对象都有其拷贝。
初始化:声明时指定初始化值、静态初始化块初始化
// static initialization block
static
{
Random generator = new Random();
nextld = generator.nextlnt(1OOOO);
}
静态final域(静态常量)
示例:Math.PI、System.out(setOut native方法)
静态方法
特点:
使用场景:
对象的三个特性:行为、状态、标识
声明
封装的好处(提供域访问器、域更改器方法mutator method、accessor method)
- 可以改变内部实现,只影响该类的代码
- 更改器方法可以执行错误检查
访问器
- 不要编写返回引用可变对象的访问器方法。若要返回,需先clone
- 类中的每个方法都不会改变其对象,这种类就是不可变类
- C++注释:const修饰的表示访问器方法
初始化
对内:访问域
类方法可以访问所属类任何对象的私有域
public boolean equals(Employee other)
{
return name.equals(other.name);
}
对外:方法调用
类型:
传值:无论是原始类型、还是引用类型变量,都会复制值
import 类、静态域、静态方法
多态的含义
枚举类的使用
反射是什么?
规则:
实现:
实现:
能够分析类能力的程序称为反射(reflective)
作用:
- 运行时分析类的能力
- 运行时查看对象
- 实现通用的操作(示例:通用数组扩容)
保存运行时的类型信息
获取Class对象
每个类型一个类对象:e.getClass() == Employee.class
创建类对象
获取域、方法:
- getFields、getMethods、getConstructors 获取类及其超类的public成员
- getDeclareFields、getDeclareMethods、getDeclareConstructors 获取全部成员(不包括超类成员)
获取值
f.get(obj) --安全管理器控制,私有域访问需覆盖访问控制
f.getDouble(obj)
设置值
f.set(obj, value)
AccessibleObject.setAccessible(true)
clazz.getMethod(name, Class… parameterTypes)
m.invoke(obj, Object…) --没有隐式参数,obj传null
公共方法:
Arrays.copyOf
问题:new Object[newLength] ——不能直接扩展数组,需要创建与原类型相同的新数组
解决:Array.newInstance()
Class.getComponentType()
Array.getLength(a)
System.arraycopy()
接口不是类,是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义
类实现接口:实现方法指定为public,否则为包可见性
注:继承情况下的反对称规则
违反时抛出ClassCastException:
注:默认方法的冲突解决?
可将接口看成没有实例域的抽象类
存在了抽象类,还需要接口:每个类只能扩展于一个类。
接口可以提供多重继承的大多数好处,同时还能避免多重继承的复杂性和低效性。
callback机制:指出某个特定事件发生时应该采取的动作
Comparator
Arrays.sort
Cloneable
如果希望copy是一个新对象,它的初始状态与original相同,但是之后它们各自会有自己不同的状态,这种情况下就可以使用clone方法
默认的clone操作是”浅拷贝“,克隆对象与原对象共享子对象为可变对象时,调用更改器方法会篡改另一对象的状态,造成不一致现象。
Cloneable接口只是作为一个标记,指示类设计者了解克隆过程
标记接口不包含任何方法;它唯一的作用就是允许在类型查询中使用 instanceof
是一个可传递的代码块,可以在以后执行一次或多次。
之前:在Java中传递一个代码段并不容易,不能直接传递代码段。Java是一种面向对象语言,所以必须构造一个对象,这个对象的类需要有一个方法能包含所需的代码。
(参数) -> 表达式
对于只有一个抽象方法的接口,当需要这个接口的对象时,就可以提供一个lambda表达式,这种接口被称为函数式接口
可能已经有现成的方法可以完成你想要传递到其他代码的某个动作
方法名为new的方法引用
可以用数组类型建立构造器引用。如int[]::new
Java有一限制:无法构造泛型类型 T 的数组,可利用数组构造器解决:
Person[] people = stream.toArray(Person[]::new);
lambda表达式有3部分:
规则:lambda表达式中捕获的变量必须实际上是最终变量
(effectively final:这个变量初始化之后就不会再为它赋新值)
在lambda中改变值,并发情况不安全。在外部改变也不允许。
this关键字,是指创建这个lambda表达式方法的this参数
使用lambda是为了:延迟执行(deferred execution)
inner class:定义在一个类中的类
For:
特殊语法规则
引用外围类表达式:OuterClass.this.beep
内部类构造器outerObject.new InnerClass(construction parameters)
外围类作用域之外引用类:OuterClass.InnerClass
内部类中声明的所有静态域都必须是 final
内部类不能有static方法。Java语言规范对这个限制没有做任何解释。也可以允许有静态方法,但只能访问外围类的静态域和方法
内部类是一种编译器现象,虚拟机对此一无所知。编译器为内部类生成了带有外部类参数的构造方法,并提供了访问外部类对象状态的静态方法
反射反编译解析字节码
java reflection.ReflectionTest irmerClass.lil kingClock\STimePrinter
或
javap -private ClassName
可以创建同一个包下的类利用虚拟机指定获取内部类访问的私有变量,破坏安全性。
在方法中定义的局部类,不能用public或private访问说明符进行声明。它的作用域被限定在声明这个局部类的块中
优势:
如果只创建局部内部类的一个对象,就不必命名了,这种类被称为匿名内部类(anonymous innerclass)
new SuperType(construction parameters) {
inner class methods and data
}
匿名类不能有构造器,取而代之的是,将构造器参数传递给超类。
实现接口时不能有任何构造参数。
应用技巧:
注意:实现equals方法时,对于匿名子类getClass测试会失败;
当使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类对象。为此,可以将内部类声明为 static, 以便取消产生的引用。
For:利用代理可以在运行时创建一个实现了一组给定接口的新类,用于:
创建的类具有下列方法:
提供一个调用处理器( invocation handler)
创建代理对象:Proxy的newProxyInstance方法,参数包含
到此为止,Java 程序设计语言的基础概念整理完毕。包括Java编程中面向对象相关基础、接口相关知识,以及内部类、Java8新增的Lambda表达式等。