java技巧总结及tip

1。Java控制台输入,输出

/* * Created on 2005-4-5 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

/** * @author Zhangql * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */

public class EnterConsole

{

public static void main(String[] args) throws IOException

{ EnterConsole enterConsole = new EnterConsole();

enterConsole.printConsoleChar(); }

/** * 从控制对接收一行字符串,然后输出到控制台 * @throws IOException */

public void printConsoleLine() throws IOException

{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String str = null;

System.out.println("Enter your value:");

str = br.readLine();

System.out.println("your value is :"+str); }

/** * 从控制台接收一个字符 * 然后打印到控制台上 * @throws IOException */

public void printConsoleChar() throws IOException

{ System.out.print("Enter a Char:");

char i = (char) System.in.read();

System.out.println("your char is :"+i); } }

--------------------------------------------------------------------------------------------------------------------

2.关于 ?:的使用?:可以如下使用:

String status = (salary <1500) ? "poor" : (salary<4000) ? "middle class" : (salary< 7000) ? "upper middle class" : "upper class";

--------------------------------------------------------------------------------------------------------------------

3

//Core Java 2 Volumn I chapter 8,Basics of Event Handling
You are completely free to designate any object of a class that implements the ActionListener interface as a button listener. We prefer to use objects of a new class that was expressly created for carrying out the desired button actions. However, some programmers are not comfortable with inner classes and choose a different strategy. They locate the component that changes as a result of the event, make that component implement the ActionListener interface, and add an actionPerformed method. In our example, you can turn the ButtonPanel into an action listener:

class ButtonPanel extends JPanel implements ActionListener
{
. . .
public void actionPerformed(ActionEvent event)
{
// set background color
. . .
}
}

Then the panel sets itself as the listener to all three buttons:

yellowButton.addActionListener(this);
blueButton.addActionListener(this);
redButton.addActionListener(this);

//Core Java 2 Volumn I chapter 12,Streams
System.in is a predefined object of a subclass of InputStream that allows you to read information from the keyboard.


//Core Java 2 Volumn I chapter 12,The Complete Stream Zoo
As we said, the InputStream and OutputStream classes let you read and write only individual bytes and arrays of bytes; they have no methods to read and write strings and numbers. You need more capable child classes for this. For example, DataInputStream and DataOutputStream let you read and write all the basic Java types.

For Unicode text, on the other hand, as we said, you use classes that descend from Reader and Writer. The basic methods of the Reader and Writer classes are similar to the ones for InputStream and OutputStream.

They work just as the comparable methods do in the InputStream and OutputStream classes except, of course, the read method returns either a Unicode code unit (as an integer between 0 and 65535) or –1 when you have reached the end of the file.

Finally, there are streams that do useful stuff, for example, the ZipInputStream and ZipOutputStream that let you read and write files in the familiar ZIP compression format.

Moreover, JDK 5.0 introduces four new interfaces: Closeable, Flushable, Readable, and Appendable (see Figure 12-3). The first two interfaces are very simple, with methods

void close() throws IOException

and

void flush()

respectively. The classes InputStream, OutputStream, Reader, and Writer all implement the Closeable interface. OutputStream and Writer implement the Flushable interface.

The Readable interface has a single method

int read(CharBuffer cb)

The CharBuffer class has methods for sequential and random read/write access. It represents an in-memory buffer or a memory-mapped file (see page 696).

The Appendable interface has two methods, for appending single characters and character sequences:

Appendable append(char c)
Appendable append(CharSequence s)

The CharSequence type is yet another interface, describing minimal properties of a sequence of char values. It is implemented by String, CharBuffer, and StringBuilder/StringBuffer (see page 656).

Of the stream zoo classes, only Writer implements Appendable.

//Core Java 2 Volumn I chapter 12,The Complete Stream Zoo,Laying Stream Files
Because all the classes in java.io interpret relative path names as starting with the user's current working directory, you may want to know this directory. You can get at this information by a call to System.getProperty("user.dir").

//Core Java 2 Volumn I chapter 12,The Complete Stream Zoo
Because the backslash character is the escape character in Java strings, be sure to use // for Windows-style path names ("C://Windows//win.ini"). In Windows, you can also use a single forward slash ("C:/Windows/win.ini") because most Windows file handling system calls will interpret forward slashes as file separators. However, this is not recommended—the behavior of the Windows system functions is subject to change, and on other operating systems, the file separator may yet be different. Instead, for portable programs, you should use the correct file separator character. It is stored in the constant string File.separator.

-----------------------------------------------------------------------------------------------------------------------------------------------

4A caution about for statement

Be careful about testing for equality of floating-point numbers in loops. A for loop that looks like this

for (double x = 0; x != 10; x += 0.1) . . .


may never end. Because of roundoff errors, the final value may not be reached exactly. For example, in the loop above, x jumps from 9.99999999999998 to 10.09999999999998 because there is no exact binary representation for 0.1.

-----------------------------------------------------------------------------------------------------------------------------------------------

5 How to Read Text Input

As you know:

  • To write data in binary format, you use a DataOutputStream.

  • To write in text format, you use a PrintWriter.

Therefore, you might expect that there is an analog to the DataInputStream that lets you read data in text format. The closest analog is the Scanner class that we have used extensively. However, before JDK 5.0, the only game in town for processing text input was the BufferedReader method—it has a method, readLine, that lets you read a line of text. You need to combine a buffered reader with an input source.

BufferedReader in = new BufferedReader(new FileReader("employee.txt"));


The readLine method returns null when no more input is available. A typical input loop, therefore, looks like this:


String line;
while ((line = in.readLine()) != null)
{
dosomethingwithline
}

The FileReader class already converts bytes to Unicode characters. For other input sources, you need to use the InputStreamReader—unlike the PrintWriter, the InputStreamReader has no automatic convenience method to bridge the gap between bytes and Unicode characters.

BufferedReader in2 = new BufferedReader(new InputStreamReader(System.in));
BufferedReader in3 = new BufferedReader(new InputStreamReader(url.openStream()));


To read numbers from text input, you need to read a string first and then convert it.

String s = in.readLine();
double x = Double.parseDouble(s);


That works if there is a single number on each line. Otherwise, you must work harder and break up the input string, for example, by using the StringTokenizer utility class. We see an example of this later in this chapter.

6 String到底变了没有?   

没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。请看下列代码:   String s = "Hello";   

s = s + " world!";   

s所指向的对象是否改变了呢?从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中,s原先指向一个String对象,内容是"Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。   

通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。   

同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:   

public class Demo {   

private String s;   ...   

public Demo {   s = "Initial Value";   }   

...   

}   

而非   

s = new String("Initial Value");   

后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。   

上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。   

至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即StringBuffer。   

7 final关键字到底修饰了什么?   

final使得被修饰的变量"不变",但是由于对象型变量的本质是“引用”,使得“不变”也有了两种含义:引用本身的不变,和引用指向的对象不变。   

引用本身的不变:   

final StringBuffer a=new StringBuffer("immutable");   

final StringBuffer b=new StringBuffer("not immutable");   

a=b;//编译期错误   

引用指向的对象不变:   

final StringBuffer a=new StringBuffer("immutable");   

a.append(" broken!"); //编译通过   

可见,final只对引用的“值”(也即它所指向的那个对象的内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。这很类似==操作符:==操作符只负责引用的“值”相等,至于这个地址所指向的对象内容是否相等,==操作符是不管的。   理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它“永远不变”。其实那是徒劳的。   

8 到底要怎么样初始化(其正确性还待检验)   

本问题讨论变量的初始化,所以先来看一下Java中有哪些种类的变量。   

1. 类的属性,或者叫值域   

2. 方法里的局部变量   

3. 方法的参数   

对于第一种变量,Java虚拟机会自动进行初始化。如果给出了初始值,则初始化为该初始值。如果没有给出,则把它初始化为该类型变量的默认初始值。   

int类型变量默认初始值为0   

float类型变量默认初始值为0.0f   

double类型变量默认初始值为0.0   

boolean类型变量默认初始值为false   

char类型变量默认初始值为0(ASCII码)   

long类型变量默认初始值为0   

所有对象引用类型变量默认初始值为null,即不指向任何对象。注意数组本身也是对象,所以没有初始化的数组引用在自动初始化后其值也是null。   

对于两种不同的类属性,static属性与instance属性,初始化的时机是不同的。instance属性在创建实例的时候初始化,static属性在类加载,也就是第一次用到这个类的时候初始化,对于后来的实例的创建,不再次进行初始化。这个问题会在以后的系列中进行详细讨论。   

对于第二种变量,必须明确地进行初始化。如果再没有初始化之前就试图使用它,编译器会抗议。如果初始化的语句在try块中或if块中,也必须要让它在第一次使用前一定能够得到赋值。也就是说,把初始化语句放在只有if块的条件判断语句中编译器也会抗议,因为执行的时候可能不符合if后面的判断条件,如此一来初始化语句就不会被执行了,这就违反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句,就可以通过编译,因为无论如何,总有至少一条初始化语句会被执行,不会发生使用前未被初始化的事情。对于try-catch也是一样,如果只有在try块里才有初始化语句,编译部通过。如果在catch或finally里也有,则可以通过编译。总之,要保证局部变量在使用之前一定被初始化了。所以,一个好的做法是在声明他们的时候就初始化他们,如果不知道要出事化成什么值好,就用上面的默认值吧!   

其实第三种变量和第二种本质上是一样的,都是方法中的局部变量。只不过作为参数,肯定是被初始化过的,传入的值就是初始值,所以不需要初始化。   

9 instanceof是什么东东?   

instanceof是Java的一个二元操作符,和==,> , <是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。举个例子:   String s = "I AM an Object!";   

boolean isObject = s instanceof Object;   

我们声明了一个String对象引用,指向一个String对象,然后用instancof来测试它所指向的对象是否是Object类的一个实例,显然,这是真的,所以返回true,也就是isObject的值为True。   

instanceof有一些用处。比如我们写了一个处理账单的系统,其中有这样三个类:   

public class Bill {//省略细节}   

public class PhoneBill extends Bill {//省略细节}   

public class GasBill extends Bill {//省略细节}   

在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用instanceof来判断:   

public double calculate(Bill bill) {   

if (bill instanceof PhoneBill) {   //计算电话账单   }   

if (bill instanceof GasBill) {   //计算燃气账单   }   

...   

}   

这样就可以用一个方法处理两种子类。 然而,这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构化编程模式。只要提供两个名字和返回值都相同,接受参数类型不同的方法就可以了:   

public double calculate(PhoneBill bill) {   //计算电话账单   }   

public double calculate(GasBill bill) {   //计算燃气账单   }

10 Constrained Bean Properties

A constrained property is a special kind of property a change in which can be vetoed by listeners if they so choose.

----------------------------------------------

11 字符串操作

A字符串操作之前应该先判断是否为空,

B判断字符串是否相等,用“==”容易出错,即不是总能获得正确结果(根据?),所以使用equals。

如, str != null && str.equals("dfsfdd");

或,"dsfsd".equals("dfad");

C字符串为空的两种情况:一,字符串不存在,str == null

二,字符串长度为0, str.length() == 0;

所以,字符串判空: str == null || str.length() == 0;

你可能感兴趣的:(java)