现在的位置: 首页 > 综合 > 正文

Java基础

2013年03月17日 ⁄ 综合 ⁄ 共 6542字 ⁄ 字号 评论关闭
文章目录


Java基础学习拾遗


这是我根据个人需要选取的一些零散知识点,并不成体系,但具有一定的启发性。

在这里尽可能简洁地记录一些基础学习过程中的零散知识点。

 拾遗

必要的计算机设置

这些简单的设置可以为编码工作带来便利。以WinXP为例。


  • 文件夹视图改为详细信息,并应用到所有;
  • 显示所有文件(夹);
  • 不隐藏文件扩展名;
  • 地址栏显示完整路径

标识符


 字母,下划线,美刀和数字构成,前三种可以开头

注意:integer是一个合法标识符。

 

深入理解变量的实质

 

变量绝对不是一块内存

 

下面的内容引自《C++从零开始》,对变量做了深入揭示。


变量是一个映射元素。映射表由编译器维护,表中的每一行都是这个表的一个元素(也称记录)。

表有三列:变量名、对应地址和相应类型。变量名是一个标识符,其命名规则按照上面所说的来。

当要对某块内存写入数据时,程序员使用相应的变量名进行内存的标识,而表中的对应地址就记录了这个地址,进而将程序员给出的变量名,一个标识符,映射成一个地址,因此变量是一个映射元素。而相应类型则告诉编译器应该如何解释此地址所指向的内存,是2个连续字节还是4个?是原码记录还是补码?而变量所对应的地址所标识的内存的内容叫做此变量的值。

有如下的变量解释:“可变的量,其相当于一个盒子,数字就装在盒子里,而变量名就写在盒子外面,这样电脑就知道我们要处理哪一个盒子,且不同的盒子装不同的东西,装字符串的盒子就不能装数字。”上面就是我第一次学习编程时,书上写的(是BASIC语言)。对于初学者也许很容易理解,也不能说错,但是造成的误解将导致以后的程序编写

地千疮百孔。

上面的解释隐含了一个意思——变量是一块内存。这是严重错误的!如果变量是一块内存,那么C++中著名的引用类型将被弃置荒野。变量实际并不是一块内存,只是一个映

射元素,这是致关重要的。

-----------以上内容引自《C++从零开始》

 

数据类型

四类八种: 整型四种 浮点两种 字符型和布尔型

 

各种基本数据类型的存储空间,但这实际上只是java概念上一种约束

在实际的计算机存储中,如在32位机器中,char型也是以32bit存储的。

 

关于浮点数

数学中的浮点数时连续的,如在[0,1]之间有无穷个浮点数。

但是在计算机内部不可能逐个表现他们,只能尽可能地模拟它们。

就是说在计算机中,它们是离散的。float类型使用32bit存储,可以最多表示232个浮点数。

 

 

类型转换、补码的相关知识

 

如下代码

byte b1 = 90;
byte b2 = 68;
byte b = (byte)(b1 + b2);
System.out.println(b);


 

这段代码输出的结果是 -100.


下面是非常详细的解释:

从第3行开始

对b1 + b2进行运算的时候,b1和b2首先自动转换为int类型的90和68,

相加得到int类型的156.

那么156转换为二进制后,理论上在计算机内的表示是(实际上可能略有差别)

               00000000 00000000 00000000 10011100

然后156将被强制转换为byte类型:抛弃前面三个字节,只剩10011100.

java中整型都是有符号的,即最高位表示符号位。

10011100的最高为是1,表示它是个负数。

在java中,负数以补码存储。那么10011100是负多少呢?

首先要了解原码与补码的关系。原码和补码的相互转换都是通过求反加1

因此要求10011100的原码,符号位1不变,尾数求反得到11100011,加1得到11100100,

最高为1是符号位,后7位转换为十进制为100,所以真值为-100.

 

 

Infinity

写出下列代码输出结果

double d= 1e300;

float f = (float)d;

System.out.println(f);

输出:Infinity.


double向 float转换时,如果超出float的取值范围则输出Infinity

 

数据类类型的存储

与取值范围大小没有必然关系

float 占用4个字节,long占用8个字节,但是float表示数值的范围比long大得多。

 

方法的本质

是复用性。

 

面向对象设计思想


从现实世界中客观存在的事物出发来构造软件系统,并在系统的构造中尽可能运用人类的自然思维方式。

面向对象更加强调运用人类日常生活中经常使用的思维方法与原则,如抽象、分类、继承、聚合、多态等等。

 

对象和类


对象是用计算机语言对问题域中事物的描述。对象通过属性(attribute)和方法(method)来分别对应事物所具有的静态属性和动态属性。

类是用来描述同类对象的抽象化了的概念。类中定义了这一类对象应具有的静态属性和动态属性。

类可以看成一类对象的模板,对象可以看成类的一个具体实例。

 

类之间的关系

  • uses-a 一个类的方法操纵另一个类的对象叫做dependence (依赖)
  • has-a 一个对象包含另一个类的对象叫做aggregation (聚合)
  • extends 继承
  • implements 实现
  • polymorphism 多态

 

面向对象程序设计

首先考虑几个类几个对象;

然后设计类的属性;

最后设计类之间的关系。

让合适的方法出现在合适的类中

 

各种0的区分

在ASCII表中第一个条目是null,值是0;

后面还有一个条目是字符‘0’,值是48;


前者有以下几种叫法:务必搞清楚它们是同一种东西


null零

二进制零

ASCII零

\0(读作反斜杠零)

字符串结束符

 

成员变量

Java中没有全局变量 应该叫成员变量 (表述要严谨)


成员变量可以不初始化,局部变量必须初始化

成员变量不初始化时,有其默认值


char型的默认值

其中char型的默认值值得注意 

准确的说char型的默认值是一个不可输出的字符,应该记作 ’\u0000’ 表示是UTF-16形式的,

而这个值正是上面所提到的null零、二进制零、ASCII零、反斜杠零

有些资料上面把char类型的默认值直接写作0是不准确的。

尽管char在和整型运算时,首先转化为整型数字0. (也就是’\u0000’这个字符转化为数值0.)

 

UTF-16字符写代码

貌似很无聊。。。Java代码中的字符都可以用UTF-16形式的字符来表示 

比如 public static void main(String[] args)完全可以写作

public staticvoid main(String\u005B\u005D args)

如果你高兴,还可以写作

public stativvoid main\u0028String\u005B\u005D args\u0029

 

方法重载

方法重载指一个类中可以定义多个方法,这些方法方法名相同,但参数形式有所不同。

调用时根据不同的参数列表选择对应的方法。首先进行“精确匹配”,如果找不到则进行“自动类型转换匹配”。

 

java源文件有最多一个public类

在一个java源文件中只能由一个public类。了解即可。

深入分析可以参考http://blog.csdn.net/bareheadzzq/article/details/6562211


public static void

调用main()的是java虚拟机。public 是为了让虚拟机看到。static表示调用main()不需要实例,虚拟机本来就存在,void表示没有返回值。

深入分析可以参考我的转载日志

http://blog.csdn.net/i10mg/article/details/8728728

 

内存管理

也有其他的划分方法,下面的相对简单一些

内存基本上可以划分为四个区域:stack、heap、data segment、code segment.

局部变量,包括形式参数存储在stack,用完后销毁;

new出来的对象存储在heap中,由java的垃圾回收机制自动回收。

静态变量和字符串常量存储在data segment.

 

upcasting 和 downcasting

父类型的引用指向子类型对象这就是upcasting

一个对象引用声明为父类型,却实例化了一个子类型的对象。

这时候通过该对象引用只能看到父类的属性,看不到子类自有的属性。

如想要看到子类自有的属性,需要downcasting. 即把这个引用强制转换为子类型。

这种转换实际上是转换了引用的视角。

 

当父类型引用指向子类型对象时,通过引用调用方法时,会调用子类型重写的方法,这就是所谓的overiding.


 

动态绑定

在执行期间,而非编译期间判断引用指向的对象的实际类型,根据其实际类型调用其相应的方法。


多态的条件

有继承; 

有重写 ;

父类引用指向子类对象

 

final 的意义

不被改变,

不被继承,

不被重写


class的访问修饰符

能够修饰class的权限修饰符只有public 和没有(friendly)

修饰符可以有public, abstract, final和(friendly)

内部类看作成员,所以有四个权限修饰符


Math.round()

Math.round(-11.5)的值是-11.

round()表示先加0.5,再向下取整。


"深入"二维数组

用Arrays.deepToString(arr)方法 


没有main()的Hello World

这个程序展示了不同过main()来打印Hello World的技巧。

把打印语句放到static块中,在出错之前用System.exit(0)退出

public class NoMain {
    static {
        System.out.println("Hello World");
        System.exit(0);
    }
}


fianl的类

如果将一个类声明为final, 那么只有其中的方法自动成为final, 而不包括域


抽象类

一个类即使不含抽象方法,也可声明为抽象类。抽象类变量可以引用非抽象类及其子类的对象。


异常

异常 java中异常可分为3类。

一类是Error,只能宕机了。如StackFlowError。

另一类是运行时异常。如空指针异常,数组下标越界。真正需要我们关心的是这一类。

最后一类是需要用户必须用try catch包围才可以的异常。方法注明了会抛出哪类异常,调用方法的时候必须用try,catch来捕捉异常,或者再次抛出给下一个调用它的对象。



外篇

递归列出文件目录

关键之处在于level参数,控制缩进量按照层次递增

private static void tree(File file, int level) {
 
    File[]members = file.listFiles();
     
    // initial value of indent
    Strings = "";
 
    for (int i = 0; i < level; i++) {
        // indent increases
        s+= "   ";
    }
 
    for (int i = 0; i < members.length; i++) {
 
        System.out.println(s +members[i].getName());
 
        if(members[i].isDirectory()) {
        // using recursion
            tree(members[i],level + 1);
        }
    }
}

递归删除目录

private static void delDirs(File file) {
    // 如果是文件则直接删除
    if (file.isFile()) {
        file.delete();
 
    } else if (file.isDirectory()) {
        // 如果不是文件则列出子目录
        File[]members = file.listFiles();
 
        for (File member : members) {
            // 递归调用自身(recursion)
            delDirs(members[i]);
        }
        // 最后删除自身
        file.delete();
 
    }
}

选号小程序

// numbers need to draw
int k = 6;
// numbers can draw
int n = 49;

// fill an array with 1 to 49
int[] numbers =newint[n];
for (int i = 0; i < numbers.length; i++) {
    numbers[i]= i + 1;
}

// draw k numbers and put them into a second array
int[] result =newint[k];
for (int i = 0; i < result.length; i++) {
    // make a random index between 0 and n-1
    int r = (int)((Math.random()* n));
    // pick the element at the random location
    result[i]= numbers[r];
    // move the last element into the random location
    numbers[r]= numbers[n - 1];
    // random index's value span decrease by 1 for each timeit loops
    n--;
}

// sort and print the result array
Arrays.sort(result);
System.out.println("Bet the following combination, it'll make yourich!");
for (int r : result) {
    System.out.println(r);
}

程序的关键之处在于产生result数组的for循环。首先产生一个0到48之间的值作为index,把这个index对应的值取出放到result中。然后把源数组最后一个元素移到被取走的元素位置上。这样保证不会取到重复的结果。

 

 死锁Demo

public class Resource {
    String resourceName;
    public Resource(String name) {
        this.resourceName = name;
    }
}

public class MyThread implements Runnable {

    Resource resourceA;
    Resource resourceB;
    Thread th;

    public MyThread(Resource A, Resource B,String name) {
        resourceA = A;
        resourceB = B;
        th = newThread(this);
        th.setName(name);
    }

    @Override
    public void run() {
        synchronized (resourceA) {
            System.out.println(th.getName() +" got " +resourceA.resourceName);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(th.getName() +" is waiting for "
                               +resourceB.resourceName +" to be released.");
            synchronized (resourceB) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


public class DeadLockTest {
    public static void main(String[] args) {
        Resource resource1 = new Resource("Resource1");
        Resource resource2 = new Resource("Resource2");
        MyThread myThread1 = new MyThread(resource1,resource2,"thread1");
        MyThread myThread2 = new MyThread(resource2,resource1,"thread2");
        myThread1.th.start();
        myThread2.th.start();
    }
}

运行结果:(程序未结束)

thread2 got  Resource2

thread1 got  Resource1

thread1 is waiting for Resource2 to be released.

thread2 is waiting for Resource1 to be released.

抱歉!评论已关闭.