Java基础
1. 为什么Java代码可以实现一次编写、到处运行?
JVM(Java Virtual Machine,Java虚拟机)是Java跨平台的关键。
在程序运行钱,Java源代码(.java)需要经过编译器编译为字节码文件(.class)。在程序运行时,JVM负责将字节码翻译成特定平台下的机器码并运行。即,只要在不同的平台安装对应的JVM,就可以运行字节码文件。
同一份Java源代码在不同的平台上运行,不需要做任何的改变,并且只需要编译一次。编译好的字节码文件是通过JVM这个中间的桥梁实现跨平台的。JVM是与平台相关的软件,它能将统一的字节码翻译成该平台的机器码。
PS:
1, 编译的结果是生成字节码,而不是机器码,字节码文件不能直接运行,必须通过JVM翻译成机器码才能运行。
2.跨平台的是Java程序,而不是JVM,JVM是用C/C++开发的软件,不同平台下需要安装不同版本的JVM。
2. 一个Java文件里可以有多个类么?(不包含内部类)
1. 一个Java文件里可以有多个类,但是最多只能有一个被public修饰类;
1. 如果这个Java文件中包含public修饰的类,则这个类的名称必须与Java文件名保持一直。
PS:内部类
Java中内部类分为两类四种:
第一类:定义在外部类局部位置上,分为方法(局部)内部类和匿名内部类
第二类:定义在外部类成员位置上,分为成员内部类和静态内部类
1. 局部内部类
局部内部类是指内部类定义在方法和作用域内。通俗来说,就是在外部类的方法中定义的内部类就是局部内部类。
局部内部类由于是在方法中定义的,因此,其作用域也是在方法内部中,方法外执行到,则被JVM回收。局部内部类的实例化也只能在方法中进行。
// 格式
class Outer{
public void method(){
class Inner{
}
}
}
// 访问时
class Outer{
private int age = 10;
public void method(){
final int age2=20;
class Inner{
public void show(){
System.out.println(age);
//从内部类中访问外部类方法内的变量age2,需要将变量声明为final
System.out.println(age2);
}
}
Inner i = new Inner();
i.show();
}
}
// 为什么局部内部类访问局部变量必须加final修饰?
/*
因为局部变量是随着方法的调用而调用,使用完毕就小时,而堆内存的数据并不会立即消失。所以堆内存还是使用该变量,而该变量已经没有了。为了让该值还存在,需要加final修饰。
原因是,当我们使用final修饰变量后,堆内存直接存储的是值,而不是变量名。
*/
//2.匿名内部类
// 一个没有名字的类,是内部类的简化写法
// 其本质是继承该类或者实现接口的子类匿名对象
/* 格式
new 类名/接口名(){
重写的方法();
}
*/
interface Inner{
public abstract void show();
}
class Outer{
public void method(){
new Inner(){
public void show(){
System.out.println("Hello World");
}
}.show();
}
}
class Test{
public static void main(String[] args){
Outer o = new Outer();
o.method();
}
}
// 如果匿名内部类中有多个方法
Inner i = new Inner(){
public void show(){
System.out.println("Hello World");
}
};//多态,此时 new Inner(){}表示的是接口的子类对象
//3. 成员内部类(非静态)
// 成员内部类——就是位于外部类成员位置的类
// 特点:可以使用外部类中所有的成员变量和成员方法(包括private的)
class Outer{
private int age=10;
class Inner{
public void show(){
System.out.println("Hello World");
}
}
}
class Test{
public static void main(String[] args){
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
// 创建成员内部类时
/*
1. 成员内部类不是静态内部类时
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
2. 成员内部类是静态内部类时
外部类名.内部类名 对象名 = new 外部类名.内部类名();
*/
// 成员内部类常见修饰符:private和static
// private:如果我们的内部类不想轻易被任何人访问,可以选择用private关键字修饰,这样我们无法通过直接创建对象的方法来访问,想要访问只需要在外部类中定义一个public修饰的方法,间接调用。这样的好处是,可以在这个public方法中增加一些判断语句,起到数据安全的作用。
class Outer{
private class Inner{
public void show(){
System.out.println("密码备份文件");
}
}
public void method(){
if(管理员身份){
Inner i = new Inner();
i.show();
}else{
System.out.println("你没有访问权限");
}
}
}
//规范化
class Outer{
private class Inner{
public void show(){
System.out.println("你没有访问权限");
}
}
public Iner gerInner(){
return new Inner();
}
public static void main(String[] args){
Outer outer = new Outer();
Inner i = outer.getInner();
i.show();
}
}
// 成员内部类笔试题
class Outer{
public int age=10;
public Inner{
public int age=20;
public void show(){
int age = 30;
System.out.println(age);//30
System.out.println(this.age);//20
System.out.println(Outer.this.age);//10
}
}
}
//4. 静态内部类
// 我们所知道static是不能用来修饰类的,但是成员内部类可以看做外部类中的一个成员,所以可以用static修饰,这种用static修饰的内部类我们称作静态内部类,也称作嵌套内部类.
// 特点:不能使用外部类的非static成员变量和成员方法
// 解释:非静态内部类编译后,会默认保存一个指向外部类的引用,而静态类却没有
// 即:即使没有外部类对象,也可以创建静态内部类对象,而外部类的非静态(static)成员必须依赖对象的调用,静态成员则可以直接使用类调用,不必依赖外部类的对象,所以静态内部类只能访问静态外部属性和方法。
class Outer{
int age = 10;
static age2 = 20;
public Outer(){
}
static class Inner{
public void method(){
System.out.println(age);//错误
System.out.println(age2);//20
}
}
}
public class Test{
public static void main(String[] args){
Inner in = new Outer.Inner();
in.method();
}
}
3. 说一说对Java访问权限的了解
Java语言为我们提供了三种访问修饰符,即private、protected和public,在使用这些修饰符修饰目标时,一共可以形成四种访问权限,即private、default、protected和public。
注意:在不加任何修饰符时,默认为default访问权限
在修饰成员变量和成员方法时,四种访问权限的含义为:
访问修饰符 | 同一个类内 | 同一个包 | 子类 | 任何地方 |
---|---|---|---|---|
private | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
在修饰类时,该类只有两种访问权限,对应的访问修饰的含义为
访问修饰符 | 同一个包 | 任何地方 |
---|