java 开发环境搭建
`windows`下搭建Java修饰符Java 变量源文件声明规则 Employee.java 文件代码:
synchronized 修饰符transient 修饰符
实例 volatile 修饰符 实例`instanceof `运算符
`Super `关键字的使用 `TestDog.java` 文件代码:
多态的优点多态存在的三个必要条件封装的优点Java 接口接口与类相似点:接口与类的区别:接口特性抽象类和接口的区别 标记接口 ?
枚举类成员`Java `包(`package`)import?package 的目录结构内部类
非静态内部类静态内部类匿名类本地类 java内部类的调用方式
windows下搭建可参照菜鸟教程Java 开发环境配置
写一个简单程序
public class HelloWorld {
public static void main(String []args) {
System.out.println("Hello World");
}
}
# 编译 javac HelloWorld.java # 运行 $ java HelloWorld Hello World
编写 Java 程序时,应注意以下几点:
大小写敏感:Java是大小写敏感的,这就意味着标识符 Hello与 hello是不同的。类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass。方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。主方法入口:所有的 Java 程序由 public static void main(String[] args)方法开始执行。 Java修饰符
像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:
访问控制修饰符 : default, public, protected, private非访问控制修饰符 : final, abstract, static, synchronized Java 变量
Java中主要有如下几种类型的变量
局部变量类变量(静态变量)成员变量(非静态变量)
源文件声明规则在本节的最后部分,我们将学习源文件的声明规则。当在一个源文件中定义多个类,并且还有import语句和package语句时,要特别注意这些规则。
一个源文件中只能有一个 public类一个源文件可以有多个非 public类源文件的名称应该和 public类的类名保持一致。例如:源文件中 public类的类名是 Employee,那么源文件应该命名为Employee.java。如果一个类定义在某个包中,那么 package语句应该在源文件的首行。如果源文件包含 import语句,那么应该放在 package语句和类定义之间。如果没有 package语句,那么 import语句应该在源文件中最前面。import语句和 package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。
在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似:
final double PI = 3.1415927;
byte、int、long、和short都可以用十进制、16进制以及8进制的方式来表示。
当使用字面量的时候,前缀 0 表示 8 进制,而前缀 0x 代表 16 进制, 例如:
int decimal = 100; int octal = 0144; int hexa = 0x64;
整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
转换从低级到高级。
低 ------------------------------------> 高 byte,short,char—> int —> long—> float —> double
浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入
(int)23.7 == 23; (int)-45.89f == -45Employee.java 文件代码:
import java.io.*;
public class Employee{
// 这个实例变量对子类可见
public String name;
// 私有变量,仅在该类可见
private double salary;
//在构造器中对name赋值
public Employee (String empName){
name = empName;
}
//设定salary的值
public void setSalary(double empSal){
salary = empSal;
}
// 打印信息
public void printEmp(){
System.out.println("名字 : " + name );
System.out.println("薪水 : " + salary);
}
public static void main(String[] args){
Employee empOne = new Employee("RUNOOB");
empOne.setSalary(1000.0);
empOne.printEmp();
}
}
以上实例编译运行结果如下:
$ javac Employee.java $ java Employee 名字 : RUNOOB 薪水 : 1000.0
任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。
抽象方法的声明以分号结尾,例如:public abstract sample();
synchronized 修饰符synchronized关键字声明的方法同一时间只能被一个线程访问。synchronized修饰符可以应用于四个访问修饰符。
transient 修饰符序列化的对象包含被 transient 修饰的实例变量时,java虚拟机(JVM)跳过该特定的变量。
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
实例public transient int limit = 55; // 不会持久化 public int b; // 持久化volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。
实例public class MyRunnable implements Runnable
{
private volatile boolean active;
public void run()
{
active = true;
while (active) // 第一行
{
// 代码
}
}
public void stop()
{
active = false; // 第二行
}
}
通常情况下,在一个线程调用 run() 方法(在 Runnable 开启的线程),在另一个线程调用 stop() 方法。 如果 第一行中缓冲区的 active 值被使用,那么在 第二行的 active 值为 false 时循环不会停止。
但是以上代码中我们使用了 volatile 修饰 active,所以该循环会停止。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q0IfVyiy-1646575842253)(C:UsersBZLAppDataRoamingTyporatypora-user-imagesimage-20210406171939938.png)]
instanceof运算符该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)
instanceof运算符使用格式如下:
( Object reference variable ) instanceof (class/interface type)
使用 SimpleDateFormat格式化日期
解析字符串为时间
Java 允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象
声明为 static 的方法不能被重写,但是能够被再次声明
Super关键字的使用当需要在子类中调用父类的被重写方法时,要使用 super关键字。
TestDog.java 文件代码:class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
super.move(); // 应用super类的方法
System.out.println("狗可以跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal b = new Dog(); // Dog 对象
b.move(); //执行 Dog类的方法
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XxehFESv-1646575842254)(C:UsersBZLAppDataRoamingTyporatypora-user-imagesimage-20210407100638995.png)]
多态的优点1. 消除类型之间的耦合关系2. 可替换性3. 可扩充性4. 接口性5. 灵活性6. 简化性 多态存在的三个必要条件
继承重写父类引用指向子类对象:Parent p = new Child();
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h4Cz1J7T-1646575842255)(C:UsersBZLAppDataRoamingTyporatypora-user-imagesimage-20210407103200780.png)]
构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法
封装的优点良好的封装能够减少耦合。类内部的结构可以自由修改。可以对成员变量进行更精确的控制。隐藏信息,实现细节。 Java 接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
==接口无法被实例化,但是可以被实现。==一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口与类相似点:一个接口可以有多个方法。接口文件保存在 .java结尾的文件中,文件名使用接口名。接口的字节码文件保存在 .class 结尾的文件中。接口相应的字节码文件必须在与包名称相匹配的目录结构中。 接口与类的区别:
接口不能用于实例化对象。接口没有构造方法。接口中所有的方法必须是抽象方法。接口不能包含成员变量,除了 static 和 final 变量。接口不是被类继承了,而是要被类实现。接口支持多继承。 接口特性
接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。 抽象类和接口的区别
抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。一个类只能继承一个抽象类,而一个类却可以实现多个接口。
接口的声明语法格式如下:
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
实现一个接口的语法,可以使用这个公式:
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...标记接口 ?
最常用的继承接口是没有包含任何方法的接口。
标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。
标记接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。
没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的:
建立一个公共的父接口:
正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。
向一个类添加数据类型:
这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。
values(), ordinal() 和 valueOf() 方法
enum定义的枚举类默认继承了 java.lang.Enum 类,并实现了java.lang.Seriablizable 和 java.lang.Comparable 两个接口。
values(), ordinal()和 valueOf() 方法位于 java.lang.Enum 类中:
values()返回枚举类中所有的值。ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。valueOf()方法返回指定字符串值的枚举常量。 枚举类成员
枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。
枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。
枚举类中的抽象方法实现,需要枚举类中的每个对象都对其进行实现
enum Color {
RED {
public String getColor() {// 枚举对象实现抽象方法
return "红色";
}
},
GREEN {
public String getColor() {// 枚举对象实现抽象方法
return "绿色";
}
},
BLUE {
public String getColor() {// 枚举对象实现抽象方法
return "蓝色";
}
};
public abstract String getColor();// 定义抽象方法
}
public class Test {
public static void main(String[] args) {
for (Color c : Color.values()) {
System.out.print(c.getColor() + "、");
}
}
}
Java包(package)
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间
java.lang-打包基础的类java.io-包含输入输出功能的函数
开发者可以自己把一组类和接口等打包,并定义自己的包。而且在实际开发中这样做是值得提倡的,当你自己完成类的实现之后,将相关的类分组,可以让其他的编程者更容易地确定哪些类、接口、枚举和注释等是相关的。
import? package 的目录结构类放在包中会有两种主要的结果:
包名成为类名的一部分,正如我们前面讨论的一样。包名必须与相应的字节码所在的目录结构相吻合。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rog6im0s-1646575842256)(C:UsersBZLAppDataRoamingTyporatypora-user-imagesimage-20210407114515535.png)]
内部类 非静态内部类非静态内部类,只有一个外部类对象存在的时候才有意义
package charactor;
public class Hero {
private String name; // 姓名
float hp; // 血量
float armor; // 护甲
int moveSpeed; // 移动速度
// 非静态内部类,只有一个外部类对象存在的时候,才有意义
// 战斗成绩只有在一个英雄对象存在的时候才有意义
class BattleScore {
int kill;
int die;
int assit;
public void legendary() {
if (kill >= 8)
System.out.println(name + "超神!");
else
System.out.println(name + "尚未超神!");
}
}
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
// 实例化内部类
// BattleScore对象只有在一个英雄对象存在的时候才有意义
// 所以其实例化必须建立在一个外部类对象的基础之上
BattleScore score = garen.new BattleScore();
score.kill = 9;
score.legendary();
}
}
静态内部类
package charactor;
public class Hero {
public String name;
protected float hp;
private static void battleWin(){
System.out.println("battle win");
}
//敌方的水晶
static class EnemyCrystal{
int hp=5000;
//如果水晶的血量为0,则宣布胜利
public void checkIfVictory(){
if(hp==0){
Hero.battleWin();
//静态内部类不能直接访问外部类的对象属性
System.out.println(name + " win this game");
}
}
}
public static void main(String[] args) {
//实例化静态内部类
Hero.EnemyCrystal crystal = new Hero.EnemyCrystal();
crystal.checkIfVictory();
}
}
匿名类
匿名类指的是在声明一个类的同时实例化它,使代码更加简洁精练
通常情况下,要使用一个接口或者抽象类,都必须创建一个子类
package charactor;
public abstract class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
public abstract void attack();
public static void main(String[] args) {
ADHero adh=new ADHero();
//通过打印adh,可以看到adh这个对象属于ADHero类
adh.attack();
System.out.println(adh);
Hero h = new Hero(){
//当场实现attack方法
public void attack() {
System.out.println("新的进攻手段");
}
};
h.attack();
//通过打印h,可以看到h这个对象属于Hero$1这么一个系统自动分配的类名
System.out.println(h);
}
}
本地类
本地类可以理解为有名字的匿名类
内部类与匿名类不一样的是,内部类必须声明在成员的位置,即与属性和方法平等的位置。
本地类和匿名类一样,直接声明在代码块里面,可以是主方法,for循环里等等地方
package charactor;
public abstract class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
public abstract void attack();
public static void main(String[] args) {
//与匿名类的区别在于,本地类有了自定义的类名
class SomeHero extends Hero{
public void attack() {
System.out.println( name+ " 新的进攻手段");
}
}
SomeHero h =new SomeHero();
h.name ="地卜师";
h.attack();
}
}
java内部类的调用方式
public class DotThis {
public class Inner{
public DotThis outer(){
return DotThis.this;
};
}
public static void main(String[] args) {
//DotThis dt = new DotThis();
//DotThis.Inner dti=dt.inner();
//2.第二种直接就能获取到
DotThis dotThis = new DotThis();
Inner inner = dotThis.new Inner();
}
}
h.attack(); }
}
### [java内部类的调用方式](https://www.cnblogs.com/q1359720840/p/10386106.html)
```java
public class DotThis {
public class Inner{
public DotThis outer(){
return DotThis.this;
};
}
public static void main(String[] args) {
//DotThis dt = new DotThis();
//DotThis.Inner dti=dt.inner();
//2.第二种直接就能获取到
DotThis dotThis = new DotThis();
Inner inner = dotThis.new Inner();
}
}



