一、java基本语法

一、java基本语法

1、java语言的特点是什么?
  1. 面向对象性:两个概念:1.类 2.对象 三个特性:封装、继承、多态
  2. 健壮性:吸收了C/C++的优点,祛除了C/C++影响程序健壮性的部分
  3. 跨平台性:java编写的程序可以在多个系统平台上运行
  4. 封装的作用:
    1. 隐藏对象内部的复杂性,只对外公开简单的接口
  5. 继承的作用:
    1. 减少了代码的冗余,提高了代码的可复用性
    2. 有利于功能的拓展
    3. 让类与类之间出现关系,提供了多态的前提
  6. 多态的作用:
    1. 父类的引用指向子类的对象
    2. 只有在方法调用的时候,编译器才会确定要调用的具体方法"晚绑定"
2、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?

​ 可以包含多个类,但是只能有一个类是声明为public的,而且声明为public的类必须和.java源文件的名称一致

3、为什么要设置path,或者说设置path的目的是什么?

​ 为了可以在控制台的任意位置下都可以调用jdk指定目录下的所有指令

4、JDK,JRE和JVM的关系是什么?

​ jdk = jre + 开发工具 jdk是用于开发java运用程序的软件开发工具

​ jre = jvm + 类库 jre是用来提供java应用程序时所需的环境

​ jvm 就是java虚拟机实现跨平台最核心的东西

5、标识符的命名规则需要注意那几点?
  1. 由0-9数字组成、大小写字母、_ 以及$组成
  2. 数字不能开头
  3. 不能使用java中的关键字和保留字
  4. 严格区分大小写
6、基本数据类型有哪些,以及基本数据类型的转换流程图?
  1. byte 、short 、char、int、long、float、double、boolean
  2. byte 、short 、char —>int —>long —>float —>double
  3. 计算机存储负数是以补码的方式,将一个负数的补码转换为十进制数步骤为:
    • 每一位都去反
    • 转换为十进制
    • 加上负号,再减去1
7、Math中的常量和常用方法
  1. Math类中包含用于执行基本数学运算的方法,如:初等指数,对数,平方根和三角函数
  2. Math.E = 2.718281828459045 是自然对数的底数的double值
  3. Math.PI =3.141592653589793 是PI 十分接近的double值
  4. Math.max(x,y)返回x和y中的最大值
  5. Math.min(x,y)返回x和y中的最小值
  6. Math.abs(x)返回x的绝对值
  7. 向上取整:Math.ceil(double a) 返回大于或等于a的最小整数
  8. 向下取整:Math.floor(double a) 返回小于或等于a的最大整数
  9. 四舍五入:Math.round(double a) 返回对a四舍五入的整数
  10. 产生随机数:Math.random() 返回 [0,1) 之间的一个随机数
  11. 三角运算
  12. 指数运算 Math.sqrt(double a) 对a进行开方 等等方法
8、如何将字符串转换成数值类型,又如何转换回来?
  1. 将字符串转换成数值:
    • 调用包装类方法 parse数据类型() 方法 例如:Integer.parseInt(“123”)
    • 调用包装类的构造器,将字符串传递进去 例如:int a = new Integer(“123”)
  2. 将数值类型转换成String类型:
    1. 直接在数值上面加上 双引号即可 例如:123 + “”
    2. 调用包装类方法toString() 例如:Integer.toString(123)
    3. 调用String的valueOf() 例如:String.valueOf(123)
9、Scanner的注意事项?

​ 当Scanner的nextXxx() 方法被调用触发了 InputMismatchException 异常,输入的值会保留,直到你调用了Scanner的next() 方法(必须是next()方法才行),才会丢弃当前值,进而等待下一个输入

10、异常处理中try-catch-finally 的执行顺序是什么?
  1. 没有异常时:try -> finally

    1. return在try中时:try -> finally -> return
      • 注意:就算在方法最后(finally)之后也存在return,返回的结果是不受finally的影响的
    2. return在catch中时:和return在try中一致
    3. return在finally中时:编译不报错但是会给予警告,会破坏程序的完整性,而且在finally中出现异常会覆盖掉 catch中的异常

    总结:

    1. finally中的代码总会被执行。
    2. 当try、catch中有return时,也会执行finally。return的时候,要注意返回值的类型,是否受到finally中代码的影响。
    3. finally中有return时,会直接在finally中退出,导致try、catch中的return失效。
  2. 存在异常时:try -> catch ->finally

11、String中的常用方法
  1. str.length():int 获取字符串长度
  2. str.charAt(int index): char 截取指定索引的一个字符
  3. str.getChars(int startIndex,int endIndex,char[] target, int startResource):char[] 截取多个字符串
  4. str.toCharArray(): char[] 将字符串转换为char型数组
  5. str.togetByte(): byte[] 将字符串转换为byte型数组
  6. str.equals(String str1) 和 str.equalsIgnoreCase(String str1) : boolean 比较两个字符串是否相等,前置区分大小写,后者不区分
  7. str.startsWith(String str1) 和 str.endsWith(String str2):boolean 判断是否是以 str1,str2开头或结尾
  8. str.toUpperCase() 和 str.toLowerCase() 将str全部转换为大写字母,小写字母
  9. str.concat(String str1):String 将两个字符串连接起来
  10. str.trim():String 去除字符串开始部分和结束部分的空格
  11. str.substring(int begin) 和 str.substring(int start,int end):String 从指定索引截取到指定末尾索引的字符串
  12. str.indexOf(String str1) 和 str.lastIndexOf(String str2):int 返回第一次出现str1和最后一次出现str2的索引
  13. str.compareTo(String str1) 和 str.compareToIgnoreCase(String str2):int 按照字典顺序比较字符串顺序,负数小于,0是等于 正数大于,后面方法不区分大小写
  14. str.replace(String str1,String str2) :String使用str2替换str中str1的部分
  15. str.contains(String str1):boolean 返回str是否包含str1
12、StringBuffer、StringBuilder中的常用方法
  1. strB.append(String str) 追加str到StrB的后面
  2. strB.insert(int index,String str) 将str插入到strB指定索引的后面
  3. strB.delete(int beginIndex,int endIndex) 删除指定开始索引和结束索引之间的字符串
  4. strB.replace(String str1,String str2) 使用str2将strB中的str1替换掉
13、如何将字符串反转,例如如何将 “abc123” 反转为 “321cba”?
  1.         String str = "abc123";
    	//方法一:调用StringBuilder的reverse() 方法
        str = new StringBuilder(str).reverse().toString();
    
  2.         //方法二:将Sting转换为char型数组
            char[] chars = str.toCharArray();
            String strChar = "";
            for (int i = chars.length - 1; i >= 0; i--) {
                strChar += chars[i];
            }
            System.out.println(strChar);
    
  3. 		//方法三:将String转换成char型数组 然后移动元素再复制给str
       		char[] chars = str.toCharArray();
            for (int i = 0; i < chars.length / 2; i++) {
                char temp = chars[i];
                chars[i] = chars[chars.length - 1 - i];
                chars[chars.length - 1 - i] = temp;
            }
            System.out.println(String.valueOf(chars));
    
  4.         //方法四:利用String中的charAt(int index) 方法
            for (int i = str.length() - 1; i >= 0; i--) {
                strChar += str.charAt(i);
            }
            System.out.println(strChar);
    
14、String 、StringBuilder 、StringBuffer 之间的区别?
  1. String、StringBuilder、StringBuffer 是被 final关键词修饰的所以不能被继承而且也并不属于基本数据类型
  2. 对于String 中的 + 运算符实际上调用的是StringBuilder类的append() 方法
    • 在使用“+”运算符的时候:会创建String 和 StringBuilder对象,使用StringBuilder的append()方法,从左到右依次添加字符串到StringBuilder中,最后再调用toString() 方法返回字符串对象String
  3. String 线程安全 字符串不可变,当进行拼接时都会产生一个新的String 并丢弃旧的String以进行垃圾回收
  4. StringBuffer 线程安全 字符串可变,jdk1.0的时候出现
  5. StringBuilder 线程不安全 字符串可变,jdk5.0的时候出现
  6. 性能 StringBuilder > StringBuffer > String
15、数组有什么特点?
  1. 数组在内存中是连续的一片空间,其长度是确定的,数组一旦创建完成,其长度就不可改变
  2. 数组元素必须是相同数据类型,不能出现混合的类型
  3. 数组中的元素类型可以是任意数据类型,可以是基本数据类型,也可以是引用数据类型
16、Arrays中的常用方法有哪些?
  1. java.util.Arrays类即为操作数组的工具类,包含了用来操作数组的各种方法
  2. boolean equals(Object[] a,Object[]b) 用来判断 数组a和数组b是否相等
  3. String toString(Object[] a) 输出数组信息
  4. void fill(Object[] target,Object val) 将指定的val值填入数组中去
  5. void sort(Object[] a) 对数组进行排序
  6. int binarySearch(Object[] a,Object key) 二分法查找指定内容
  7. Arrays.asList(Object[] target) 将数组转换为集合
  8. Arrays.copyOf(Object[] target) 对数组的拷贝
17、方法重载和方法重写的区别是什么?
  1. 方法的重写是多态的体现,被称为”晚绑定“而重载是”早绑定“
  2. 重载发生在一个类中,而且方法的参数列表必须不同,对于返回值类型和异常没有要求,重写发生在子类与父类之间参数列表必须相同,返回值类型只能是父类返回值类型或者父类返回值类的子类,若抛出异常也必须是父类抛出的异常或异常子类
18、方法的值传递机制是怎样的?
  1. java中的参数传递方式只有一种:值传递
  2. 形参是基本数据类型:将实参的基本类型的变量的数据值传递给形参
  3. 形参是引用数据类型:将实参的引用数据类型的地址值传递给形参
    • 包装类传递的依然是数据值,因为有自动装箱和自动拆箱的存在
19、关于递归的经典问题
  1. 递归:一个方法体内调用它自身,包含了一种隐式的循环,但是一定要向已知的方向进行递归,否则就是死循环了
  2. n!
  3. 汉诺塔问题
  4. 快速排序
  5. 斐波那契数列 1 1 2 3 5 8 13……
20、关于javaBean
  1. 含有一个无参构造器
  2. 提供getter、setter方法
  3. 属性使用private修饰
21、java中的包管理机制
  1. 包可以包含类和子包,划分项目层次,便于管理
  2. 可以解决命名冲突的问题
  3. 可以控制访问权限
22、关于Object类
  1. Object类是java所有类的根父类
  2. 在类的声明中没有使用extends关键字指明其直接父类,默认直接父类都是java.lang.Object类
  3. x instanceof A 使用来判断 x对象是否是A类型或者A的子类
  4. Object中声明了一些通用的方法:
    1. clone() 创建并返回此对象的副本
    2. equals() 判断对象是否相等,Object中用的还是==,要判断内容具体的子类还是要重写的
    3. getClass() 获取当前类的运行时类对象
    4. hashCode() 获取对象的hash值
    5. notify() 唤醒正在等待同步监视器的单个线程
    6. notifyAll() 唤醒正在等待同步监视器的全部线程
    7. toString() 返回对象的字符串表示形式
    8. wait() 当前线程等待,知道另一个线程调用 notify() 或 notifyAll() 方法
23、关于包装类
@Test
    public void test6(){

        /**
         * 为什么会出现char[]使用print打印的时候是值,而不是地址值呢?
         * print() 方法有许多重载的方法,其他数据类型用print() 输出时调用的是print(Object obj)
         * 而char[] 输出时调用的其实是 print(char[] chars) 在print(char[] chars)的方法执行输出时
         * 将该数组执行了一个遍历操作
         */
        char[] arr = new char[] { 'a', 'b', 'c' };
        System.out.println(arr);//a,b,c
        int[] arr1 = new int[] { 1, 2, 3 };
        System.out.println(arr1);//地址值
        double[] arr2 = new double[] { 1.1, 2.2, 3.3 };
        System.out.println(arr2);//地址值

        /**
         * 对于三元运算符 :
         * 运算符——被称为运算符,那就符合运算符的特点,运算符有什么特点?
         * 运算符会将当前参与运算的变量提升到当前变量中数据类型最高的类型再进行运算
         * 本例中double的数据类型比int类型要高,所以要将int类型转换为double类型
         */
        Object o1 = true ? new Integer(1) : new Double(2.0);
        System.out.println(o1);//
        Object o2;
        if (true)
            o2 = new Integer(1);
        else
            o2 = new Double(2.0);
        System.out.println(o2);//

        /**
         * Integer内部定义了一个 IntegerCache的结构,IntegerCache中定义了 Integer[],
         * Integer[]数组保存了从 -128~127范围内的整数,如果我们会使用自动装箱的方式,
         * 在Integer[] 范围内时,可以直接使用数组的中的元素,不用去new了,目的:提高效率
         *
         */
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System.out.println(i == j);//false
        Integer m = 1;
        Integer n = 1;
        System.out.println(m == n);//true
        Integer x = 128;
        Integer y = 128;
        System.out.println(x == y);//false
    }
24、关于final关键字的两道面试题
public class Something {
	public int addOne(final int x) {
		return ++x;
        //报错, ++x 中包含两个动作 1.给x+1,2.将值赋给x 而x被final修饰不能被修改所以编译错误
		// return x + 1;//通过,并没有给x进行赋值
	}
}

public class Something {
	public static void main(String[] args) {
		Other o = new Other();
		new Something().addOne(o);
	}
	public void addOne(final Other o) {
		// o = new Other();//报错o被 final修饰是不能够被改变的
		o.i++;//通过,我们只是修改o里面的i变量,并没有修改o,归根结底o中的i还是变量
	}
}
class Other {
	public int i;
}
25、关于接口
  1. 所有的成员变量默认都是由 public static final 修饰的

  2. 所有的抽象方法默认都是由 public abstract 修饰的

  3. 没有构造器

  4. 接口采用多继承方式

    //问题一:
    interface A {
    	int x = 0;
    }
    class B {
    	int x = 1;
    }
    class C extends B implements A {
    	public void pX() {
    		System.out.println(x);//编译报错,分不清哪个里面的x,可以修改为:
            //若想调用父类的x,可以使用super关键字
            System.out.println(super.x);
            //若想调用接口中的x,可以使用 A.x 因为接口中的成员变量默认都是 public static final修饰的
            System.out.println(A.x);
    	}
    	public static void main(String[] args) {
    		new C().pX();
    	}
    }
    //问题二:
    interface Playable {
    	void play();
    }
    interface Bounceable {
    	void play();
    }
    interface Rollable extends Playable, Bounceable {
    	Ball ball = new Ball("PingPang");
    }
    class Ball implements Rollable {
    	private String name;
    	public String getName() {
    		return name;
    	}
    	public Ball(String name) {
    		this.name = name;
    	}
    	public void play() {//此行并不会报错,默认将上面两个接口中的play都实现了
    		ball = new Ball("Football");//编译报错,在上面的接口中已经声明并赋值了ball变量,
            //此时要注意接口中的成员变量是public static final修饰的,
            //所有我们不能对final修饰的变量进行修改
    		System.out.println(ball.getName());
    	}
    }
    
  5. jdk 8.0 的接口新特性

    1. 接口中可以定义静态方法public static,但是只能通过接口来进行调用,实现类是看不到此方法的

    2. 接口中可以定义默认方法public default, 子类重写的时候要把default关键字去掉,通过实现类的对象可以调用

    3. 如果子类(或实现类)捷诚得父类和实现的接口中声明了同名同参数的默认方法,子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法 ——>类优先原则

    4. 如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,在实现类没有重写此方法的情况下,会报错 ——> 接口冲突,所以我们必须要在实现类中重写此方法

    5. 如何在子类(或实现类)的方法中调用父类、接口中被重写的方法呢?

      //调用父类中的方法
      super.method();
      //调用接口中的默认方法
      InterfaceA.super.method();
      
26、类的加载过程
public class Father {
    private int i = test();
    private static int j = method();
    static {
        System.out.println("(1)");
    }
    Father(){
        System.out.println("(2)");
    }
    {
        System.out.println("(3)");
    }
    public int test(){
        System.out.println("(4)");
        return 1;
    }
    public static int method(){
        System.out.println("(5)");
        return 1;
    }
}
public class Son extends Father{
    private int i = test();
    private static int j = method();
    static {
        System.out.println("(6)");
    }
    public Son(){
        System.out.println("(7)");
    }
    {
        System.out.println("(8)");
    }
    public int test(){
        System.out.println("(9)");
        return 1;
    }
    public static int method(){
        System.out.println("(10)");
        return 1;
    }

    public static void main(String[] args) {
        //1.不创建对象时,输出的顺序为:
        // (5) (1) (10) (6)
        /**
         * 解释:
         */
        //2.创建一个对象时,输出的顺序为:
        //(5) (1) (10) (6) (9) (3) (2) (9) (8) (7)
        Son son1 = new Son();
        /**
         * 解释:
         * 这里面第一个 (9) 其实是父类 test() 方法执行,但是由于该方法被子类重写了,所以输出的是 (9)
         * 属性 代码块 构造器
         * 属性 和 代码块 谁写在前面谁就先执行
         * 构造器总是最后才执行的,(你想呀,构造器要注入属性的,肯定要先把属性加载才可以呀)
         * 构造器中总是 将 super() 放在第一位
         * 那些方法不能重写:
         *  1. final修饰的方法
         *  2. static修饰的方法
         *  3. private修饰的方法
         */
        System.out.println();
        //3.创建第二个对象时,输出的顺序为:
        //(5) (1) (10) (6) (9) (3) (2) (9) (8) (7) (9) (3) (2) (9) (8) (7)
        Son son2 = new Son();
        /**
         * 解释:
         */
    }
}

你可能感兴趣的:(Java基础,java)