• Java基础概念


    java与javac是在JDK同一目录下两个文件,为什么可以直接运行java不能直接运行javac?

           很多同学一开始学习Java的时候并没有直接用Eclipse这样的IED(Integrated Development Environment)来编写,这时候安装JDK(Java Development Kit)之后大概第一件事就是要配置path 以便能够编译 .java文件,那为什么在没有配置path的时候我们就可以运行和javac.exe同样放在一个目录(例如 *\jdk1.6.0_11\bin)里的java.exe呢?

      答案就是Sun公司为方便安装完JDK可直接运行java类文件,在后台将java文件加入到PATH的搜索路径中。(但是没有找到是在哪里设置的)

    main() 函数为什么是 public static void 的?

           最开始学习在控制台打印 Hello World  的时候我们就开始用这一句代码,有些书在开头讲的时候会告诉我们先不用管这一句话的意思,只要记住以后会讲解。现在我们知道程序开始运行都是从main函数开始的,那么为什么非得用public static void 这三个关键字来修饰 main 呢?

           因为main函数由虚拟机(jvm)调用,jvm在试图运行一个类之前先检查该类是否存在可以被运行的方法,这个方法必须是公有(public)的,以便在任何位置都能访问得到,其次运行这个方法不能依赖于用对象来调用它,因为这时候还没有对象产生,所以必须是static 的,void 就是jvm执行后不需要返回值。

           其实jvm要运行一个java程序,不一定是非要求它包含main方法的,在jvm加载类的时候,会首先运行该类的静态块,静态块运行完之后才会寻找main方法,如果没有main方法,程序就会抛出异常(Exception in thread "main" java.lang.NoSuchMethodError: main)。当然这主要了解的是jvm加载类的过程,实际中没有用这种方法来执行程序的。

    例如下面的几行代码:

    public class Test {
        static {
            System.out.println("hello");
        }
    }

    在jvm加载类Test的时候static中的代码就会输出 hello ,然后才去寻找main方法。注意:这段代码在大部分IDE里是不能运行的,需要在命令行中才能看到结果。

    i++问题

    int i = 0;
    i = i++;
    System.out.println("i="+i);

         这也是网上经常出现的一个问题,答案是 i=0。

         原因是在定义 i 的时候,会在缓冲区中定义一个变量 i' ,平时谈到的 i++ 先赋值再加一说的应该就是缓冲区中的变量先赋值,即 i' = 0; 再取源地址的值加一,      即 i = i + 1;然后再把缓冲区中的值赋给 i , 即 i = i'; 所以 +1 没有成功,i 还是0 。

         但是 Java和 C语言在这一问题上是不同的,详细的信息请见 yjwgeg 的这篇文章http://www.java3z.com/cwbwebhome/article/article2/2158.html

    比较 x = x+1;     x += 1;     x++;     的效率

    我们可以分别看看三个加一运算执行的步骤:

    首先

    x = x+1; 效率最低,执行步骤如下:

         1)读取右 x 的地址;

         2)x + 1;

         3)读取左 x 的地址;

         4)将右值传给左侧的 x (两边的数相当于两个数 x,y。编译器并不认为左右 x 的地址相同)

    其次    

    x += 1; 执行步骤如下:

         1)读取 x 地址;

         2)x + 1;

         3)将得到的值传给 x (因为 x 的地址已经读出)

    最高的是 x++;执行步骤如下:

         1)读取 x 的地址;

         2)x 自增 1

    类型转换

         short  s = 1;

         s = s + 1;     编译错误

         short s = 1;

         s += 1;     编译通过

    解释:当两个操作数类型都不高于 int 型时,运算的结果会自动向 int 型转换,当其中只要有一个操作数类型高于 int 为 long 型时,运算的结果便会向 long 型转换。

         例如: byte b1 = 0;

                   long b2 = 1;

                   b1 + b2 则为 long 型;

                   short a1 = 0;

                   short a2 = 1;

                   a1 + a2 则为 int 型;

         可见编译器所做的这些目的就是为了保证运算的精度;

         当使用 +=、-=、*=、/=、%= 运算符对基本类型进行运算时,遵循如下规则:运算符右侧的数值将首先被强制转换成与运算符左侧数值相同的类型,然后再进行运算,且运算结果与左边数值类型相同;

         所以在执行 s += 1; 时,编译可以通过。

    断言 assert

         assert 布尔表达式 , 用于调试

         断言的两种类型:

         1)assert Expression 1;

         2)assert Expression 1(产生布尔值) : Expression 2(得出任意值表达式,用于生成更多调试信息);

    默认情况下禁用

         启用: -enableassertions 或 -ea 标记

         禁用: - da 或 -disableassertions

         可在预计正常情况不会到达的任何位置放置断言,可用于验证传递给私有方法的参数。(不管是否启用断言,公有方法都要检查参数)

         断言不该以任何方式改变程序的状态。

     

     

  • 相关阅读:
    Python连接MySQL乱码(中文变问号)
    mysql学习04 pymysql 学习
    mysql学习03
    多态与多态性
    重用父类功能的两种方式
    菱形继承问题
    组合
    继承的应用和派生的概念引出
    类的继承
    类与类型
  • 原文地址:https://www.cnblogs.com/yuxiaoqi/p/2709026.html
Copyright © 2020-2023  润新知