Java的特点
1.Java是一门面向对象的编程语言。面向对象和面向过程是一种软件开发思想。
面向过程就是分析出解决问题所需要的步骤,然后用函数按这些步骤实现,使用的时候依次调用就可以了。面向对象是把构成问题事务分解成各个对象,分别设计这些对象,然后将他们组装成有完整功能的系统。面向过程只用函数实现,面向对象是用类实现各个功能模块。
例如五子棋,面向过程的设计思路就是首先分析问题的步骤:
1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。
把上面每个步骤用分别的函数来实现,问题就解决了。而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为: 1、黑白双方 2、棋盘系统,负责绘制画面 3、规则系统,负责判定诸如犯规、输赢等。
黑白双方负责接受用户的输入,并告知棋盘系统棋子布局发生变化,棋盘系统接收到了棋子的变化的信息就负责在屏幕上面显示出这种变化,同时利用规则系统来对棋局进行判定。
2.Java具有平台独立性和移植性。
- Java有一句口号:Write once, run anywhere,一次编写、到处运行。这也是Java的魅力所在。而实现这种特性的正是Java虚拟机JVM。已编译的Java程序可以在任何带有JVM的平台上运行。你可以在windows平台编写代码,然后拿到linux上运行。只要你在编写完代码后,将代码编译成.class文件,再把class文件打成Java包,这个jar包就可以在不同的平台上运行了。
3.Java具有稳健性。
- Java是一个强类型语言,它允许扩展编译时检查潜在类型不匹配问题的功能。Java要求显式的方法声明,它不支持C风格的隐式声明。这些严格的要求保证编译程序能捕捉调用错误,这就导致更可靠的程序。
- 异常处理是Java中使得程序更稳健的另一个特征。异常是某种类似于错误的异常条件出现的信号。使用try/catch/finally语句,程序员可以找到出错的处理代码,这就简化了出错处理和恢复的任务。
JKD和JRE
JDK和JRE是Java开发和运行工具,其中JDK包含了JRE,而JRE是可以独立安装的。
JDK
Java Development
Kit,JAVA语言的软件工具开发包,是整个JAVA开发的核心,它包含了JAVA的运行(JVM+JAVA类库)环境和JAVA工具。
JRE
JRE(Java Runtime
Environment,Java运行环境):包含JVM标准实现及Java核心类库。JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器)。JRE是运行基于Java语言编写的程序所不可缺少的运行环境。也是通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。
Java基础语法
基本数据类型
- byte,8bit
- char,16bit
- short,16bit
- int,32bit
- float,32bit
- long,64bit
- double,64bit
- boolean,只有两个值:true、false,可以使⽤用 1 bit 来存储,但是具体⼤小没有明确规定。
包装类型
基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值通过自动装箱与拆箱完成。
Integer x = 1; // 装箱 调⽤ Integer.valueOf(1)
int y = x; // 拆箱 调⽤了 X.intValue()
包装类缓存
使用Integer.valueOf(i)生成Integer,如果 -128 <= i <= 127,则直接从cache取对象返回,不会创建新的对象,避免频繁创建包装类对象。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
String
String是final类,不可被继承。
String拼接
字符串拼接可以使用String用+做拼接,也可以使用StringBuilder和StringBuffer实现,三种方式对比:
- 底层都是char数组实现的
- 字符串拼接性能:StringBuilder > StringBuffer > String
- String 是字符串常量,一旦创建之后该对象是不可更改的,用+对String做拼接操作,实际上是先通过建立StringBuilder,然后调用append()做拼接操作,所以在大量字符串拼接的时候,会频繁创建StringBuilder,性能较差。
- StringBuilder和StringBuffer的对象是字符串变量,对变量进行操作就是直接对该对象进行修改(修改char[]数组),所以速度要比String快很多。
- 在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的,StringBuffer中很多方法带有synchronized关键字,可以保证线程安全。
关键字
static
static可以用来修饰类的成员方法、类的成员变量。
静态变量
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
//以下例子,age为非静态变量,则p1打印结果是:Name:zhangsan, Age:10;若age使用static修饰,则p1打印结果是:Name:zhangsan, Age:12,因为static变量在内存只有一个副本。
public class Person {
String name;
int age;
public String toString() {
return "Name:" + name + ", Age:" + age;
}
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "zhangsan";
p1.age = 10;
Person p2 = new Person();
p2.name = "lisi";
p2.age = 12;
System.out.println(p1);
System.out.println(p2);
}
/**Output
* Name:zhangsan, Age:10
* Name:lisi, Age:12
*///~
}
静态方法
static方法一般称作静态方法。静态方法不依赖于任何对象就可以进行访问,通过类名即可调用静态方法。
public class Utils {
public static void print(String s) {
System.out.println("hello world: " + s);
}
public static void main(String[] args) {
Utils.print("程序员小志");
}
}
静态代码块
静态代码块只会在类加载的时候执行一次。以下例子,startDate和endDate在类加载的时候进行赋值。
class Person {
private Date birthDate;
private static Date startDate, endDate;
static{
startDate = Date.valueOf("1996");
endDate = Date.valueOf("2021");
}
public Person(Date birthDate) {
this.birthDate = birthDate;
}
}
静态内部类
在静态方法里,使用⾮静态内部类依赖于外部类的实例,也就是说需要先创建外部类实例,才能用这个实例去创建非静态内部类。⽽静态内部类不需要。
public class OuterClass {
class InnerClass {
}
static class StaticInnerClass {
}
public static void main(String[] args) {
// 在静态方法里,不能直接使用OuterClass.this去创建InnerClass的实例
// 需要先创建OuterClass的实例o,然后通过o创建InnerClass的实例
// InnerClass innerClass = new InnerClass();
OuterClass outerClass = new OuterClass();
InnerClass innerClass = outerClass.new InnerClass();
StaticInnerClass staticInnerClass = new StaticInnerClass();
outerClass.test();
}
public void nonStaticMethod() {
InnerClass innerClass = new InnerClass();
System.out.println("nonStaticMethod...");
}
}
final
1.基本数据类型用final修饰,则不能修改,是常量;对象引用用final修饰,则引用只能指向该对象,不能指向别的对象,但是对象本身可以修改。
2.final修饰的方法不能被子类重写
3.final修饰的类不能被继承。
this
this.属性名称指访问类中的成员变量,可以用来区分成员变量和局部变量。如下代码所示,this.name访问类Person当前实例的变量。
/**
* @description:
* @author: 程序员小志
* @time: 2021-11-23 11:01
*/
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
this.方法名称用来访问本类的方法。以下代码中,this.born()调用类 Person 的当前实例的方法。
/**
* @description:
* @author: 程序员小志
* @time: 2021-11-23 11:01
*/
public class Person {
String name;
int age;
public Person(String name, int age) {
this.born();
this.name = name;
this.age = age;
}
void born() {
}
}
super
super 关键字用于在子类中访问父类的变量和方法。
class A {
protected String name = "小志";
public void getName() {
System.out.println("父类:" + name);
}
}
public class B extends A {
@Override
public void getName() {
System.out.println(super.name);
super.getName();
}
public static void main(String[] args) {
B b = new B();
b.getName();
}
/**
* 小志
* 父类:小志
*/
}
在子类B中,我们重写了父类的getName()方法,如果在重写的getName()方法中我们要调用父类的相同方法,必须要通过super关键字显式指出。
object常用方法
Java面试经常会出现的一道题目,Object的常用方法。下面给大家整理一下。
- object常用方法有:toString()、equals()、hashCode()、clone()等。
toString
默认输出对象地址。
public class Person {
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public static void main(String[] args) {
System.out.println(new Person(18, "程序员小志").toString());
}
//output
//me.tyson.java.core.Person@4554617c
}
可以重写toString方法,按照重写逻辑输出对象值。
public class Person