Thinking in Java notes (1~10)
一,数据类型测试
class A{
public int i;
public double d;
public float f;
public long l;
public boolean b;
public char c;
public short s;
public byte by;
}
public class ClassTest {
public static void main(String args[]){
A a = new A();
System.out.println("a.i="+a.i);
System.out.println("a.d="+a.d);
System.out.println("a.b="+a.b);
System.out.println("a.by="+a.by);
System.out.println("a.c="+a.c);
System.out.println("a.s="+a.s);
System.out.println("a.f="+a.f);
}
}
输出的结果为:
a.i = 0
a.d = 0.0
a.c = a
a.s = 0
a.f = 0.0
a.b = false
a.by = 0;
解释:
因为类地成员变量默认初始化,一个字符的默认初始化为ASCII值为000的字符
ASCII值为000的字符变为字符在dos下显示为a (jdk 1.6.0.8)
假若在ClassTest类里面加上 int m ;则必须初始化 不然报错
二,一个类能够被public ,static,friendly 修饰
三,static测试
class A{
public A(){
System.out.println("hello I am A ");
}
static{
System.out.println("hello I am A static");
}
}
class ClassTest{
static{
System.out.println("hello I am ClassTest ");
}
public static void main(String args[]){
A a = new A();
}
}
输出结果:
hello I am ClassTest
hello I am A static
hello I am A
解释:static 块先于构造函数,属于静态绑定。而类对象的生成属于动态绑定。
四,自动增长测试
public class AutoInc {
public static void main(String[] args){
int i = 1;
System.out.println("i : " + i);
System.out.println("++i : " + ++i); // Pre-increment
System.out.println("i++ : " + i++); // Post-increment
//System.out.println("i : " + i);
System.out.println("--i : " + --i); // Pre-decrement
System.out.println("i-- : " + i--); // Post-decrement
System.out.println("i : " + i);
}
}
输出结果:
"i : 1",
"++i : 2",
"i++ : 2",
"i : 3",
"--i : 2",
"i-- : 2",
"i : 1"
五 测试equals
class Value {
int i;
}
public class EqualsMethod {
public static void main(String[] args) {
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1.equals(n2));
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100; //表示指向同一个数据
System.out.println(new Integer(v1.i).equals(v2.i));
System.out.println(v1.equals(v2));
}
}
输出结果:
true
true
false
六 小数转换
public class CastingNumbers {
public static void main(String[] args){
double above = 0.7, below = 0.4;
System.out.println("above: " + above);
System.out.println("below: " + below);
System.out.println("(int)above: " + (int)above);
System.out.println("(int)below: " + (int)below);
System.out.println("(char)('a' + above): " + (char)('a' + above));
System.out.println("(char)('a' + below): " + (char)('a' + below));
}
}
结果:
above: 0.7
below: 0.4
(int)above: 0
(int)below: 0
(char)('a' + above): a
(char)('a' + below): a
解释: 将一个 float 或double 值转型成整数值后,总是将小数部分“砍掉”
(而不是四舍五入)。
,方法重载
//import java.util.*;
class Tree {
int height;
Tree() {
System.out.println("Planting a seedling");
height = 0;
}
Tree(int i) {
System.out.println("Creating new Tree that is "
+ i + " feet tall");
height = i;
}
void info() {
System.out.println("Tree is " + height + " feet tall");
}
void info(String s) {
System.out.println(s + ": Tree is "
+ height + " feet tall");
}
}
public class Overload {
public static void main(String[] args) {
for(int i = 0; i < 5; i++) {
Tree t = new Tree(i);
t.info();
t.info("overloaded method");
}
// Overloaded constructor:
new Tree();
}
}
解释:
方法重载一定要方法名相同,参数不同(类型,顺序,个数)
** 构造方法和普通方法都可以重载。
附加: 基本类型的重载
基本类型能从一个“较小”的类型自动提升至一个“较大”的类型,此过程一旦牵涉到重载,可能会造成一些混淆。以下例子说明了将基本类型传递给重载方法时发生的情况:
public class PrimitiveOverloading{
void f1(char x) { System.out.println("f1(char)"); }
void f1(byte x) { System.out.println("f1(byte)"); }
void f1(short x) { System.out.println("f1(short)");}
void f1(int x) { System.out.println("f1(int)"); }
void f1(long x) { System.out.println("f1(long)"); }
void f1(float x) { System.out.println("f1(float)"); }
void f1(double x) { System.out.println("f1(double)"); }
void f2(byte x) { System.out.println("f2(byte)"); }
void f2(short x) { System.out.println("f2(short)"); }
void f2(int x) { System.out.println("f2(int)"); }
void f2(long x) { System.out.println("f2(long)"); }
void f2(float x) { System.out.println("f2(float)"); }
void f2(double x) { System.out.println("f2(double)"); }
void f3(short x) { System.out.println("f3(short)"); }
void f3(int x) { System.out.println("f3(int)"); }
void f3(long x) { System.out.println("f3(long)"); }
void f3(float x) { System.out.println("f3(float)"); }
void f3(double x) { System.out.println("f3(double)"); }
void f4(int x) { System.out.println("f4(int)"); }
void f4(long x) { System.out.println("f4(long)"); }
void f4(float x) { System.out.println("f4(float)"); }
void f4(double x) { System.out.println("f4(double)"); }
void f5(long x) { System.out.println("f5(long)"); }
void f5(float x) { System.out.println("f5(float)"); }
void f5(double x) { System.out.println("f5(double)"); }
void f6(float x) { System.out.println("f6(float)"); }
void f6(double x) { System.out.println("f6(double)"); }
void f7(double x) { System.out.println("f7(double)"); }
void testConstVal() {
System.out.println("Testing with 5");
f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);
}
void testChar() {
char x = 'x';
System.out.println("char argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testByte() {
byte x = 0;
System.out.println("byte argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testShort() {
short x = 0;
System.out.println("short argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testInt() {
int x = 0;
System.out.println("int argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testLong() {
long x = 0;
System.out.println("long argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testFloat() {
float x = 0;
System.out.println("float argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testDouble() {
double x = 0;
System.out.println("double argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
public static void main(String[] args) {
PrimitiveOverloading p = new PrimitiveOverloading();
p.testConstVal();
p.testChar();
p.testByte();
p.testShort();
p.testInt();
p.testLong();
p.testFloat();
p.testDouble();
}
}
结果:
"Testing with 5",
"f1(int)",
"f2(int)",
"f3(int)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"char argument:",
"f1(char)",
"f2(int)",
"f3(int)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"byte argument:",
"f1(byte)",
"f2(byte)",
"f3(short)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"short argument:",
"f1(short)",
"f2(short)",
"f3(short)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"int argument:",
"f1(int)",
"f2(int)",
"f3(int)",
"f4(int)",
"f5(long)",
"f6(float)",
"f7(double)",
"long argument:",
"f1(long)",
"f2(long)",
"f3(long)",
"f4(long)",
"f5(long)",
"f6(float)",
"f7(double)",
float argument:
f1(float)
f2(float)
f3(float)
f4(float)
f5(float)
f6(float)
f7(double)
double argument:
f1(double)
f2(double)
f3(double)
f4(double)
f5(double)
f6(double)
f7(double)
解释:
一个常数默认为int型
按照大小来自动提升的
float比long大,比double小
八 , this 关键字
public class Leaf {
int i = 0;
Leaf increment() {
i++;
return this;
}
void print(){
System.out.println("i = " + i);
}
public static void main(String[] args){
Leaf x = new Leaf();
x.increment().increment().increment().print();
}
}
结果: i = 3;
解释:
由于increment( )通过this 关键字返回了对当前对象的引用,所以很容易在一条语句里对同
一个对象执行多次操作。
在构造器调用构造器
public class Flower {
int petalCount = 0;
String s = new String("null");
Flower(int petals) {
petalCount = petals;
System.out.println("Constructor w/ int arg only, petalCount= " + petalCount);
}
Flower(String ss) {
System.out.println("Constructor w/String arg only, s=" + ss);
s = ss;
}
Flower(String s, int petals) {
this(petals);
//! this(s); // Can't call two!
this.s = s; // Another use of "this"
System.out.println("String & int args");
}
Flower(){
this("hi", 47);
System.out.println("default constructor(no args)");
}
void print() {
//! this(11); // Not inside non-constructor!
System.out.println("petalCount = " + petalCount + " s = "+ s);
}
public static void main(String[] arg){
Flower x = new Flower();
x.print();
}
}
结果:
"Constructor w/ int arg only, petalCount= 47",
"String & int args",
"default constructor (no args)",
"petalCount = 47 s = hi"
解释: 构造器可以用this关键字调用 区别super(继承调用父类构造器)
九: 清除:终结与回收
1. 对象可能不被回收。
2. 垃圾回收并不等于“析构”。
3. 垃圾回收只与内存有关。
所以finalize()不能作为通用的清除方法。
**之所以要有finalize( ),是由于你可能在分配内存时,
采用了类似C语言中的做法而非Java中的通常做法。
class Book {
boolean checkedOut = false;
Book(boolean checkOut) {
checkedOut = checkOut;
}
void checkIn() {
checkedOut = false;
}
public void finalize(){
if(checkedOut)
System.out.println("Error: checked out");
}
}
public class TerminationCondition{
public static void main(String[] args){
Book novel = new Book(true);
// Proper cleanup:
novel.checkIn();
// Drop the reference, forget to clean up:
new Book(true);
// Force garbage collection & finalization:
System.gc();
}
}
结果:Error: checked out
解释:系统强制清除内存中的对象
附加:垃圾回收器如何工作的
在某些Java 虚拟机中,堆的实现截然
不同:它更象一个传送带,你每分配一个新对象,它就往前移动一格。这意味着对象存储空
间的分配速度非常快。Java 的“堆指针”只是简单地移动到尚未分配的区域,其效率比得上C++在堆栈上分配空间的效率。
十,初始化
public class InitialValues {
boolean t;
char c;
byte b;
short s;
int i;
long l;
float f;
double d;
void print(String s) {
System.out.println(s);
}
void printInitialValues(){
print("Data type Initial value");
print("boolean " + t);
print("char [" + c + "]");
print("byte " + b);
print("short " + s);
print("int " + i);
print("long " + l);
print("float " + f);
print("double " + d);
}
public static void main(String[] args){
InitialValues iv = new InitialValues();
iv.printInitialValues();
}
}
结果:
Data type Initial value",
"boolean false",
"char [" + (char)0 + "]", //dos下显示a 本人jdk 1.6验证
"byte 0",
"short 0",
"int 0",
"long 0",
"float 0.0",
"double 0.0"
10.1初始化顺序:
在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。如下;
class Tag {
Tag(int marker) {
System.out.println("Tag(" + marker + ")");
}
}
class Card{
Tag t1 = new Tag(1); // Before constructor
static {
System.out.println("static ..");
}
Card(){
// Indicate we're in the constructor:
System.out.println("Card()");
t3 = new Tag(33); // Reinitialize t3
}
Tag t2 = new Tag(2); // After constructor
void f(){
System.out.println("f()");
}
Tag t3 = new Tag(3); // At end
}
public class OrderOfInitialization {
public static void main(String[] args) {
Card t = new Card();
t.f(); // Shows that construction is done
}
}
结果:
static..
"Tag(1)",
"Tag(2)",
"Tag(3)",
"Card()",
"Tag(33)",
"f()"
解释:静态块(静态绑定)先于变量定义,
变量定义先于方法(如构造器)(动态绑定)初始化。
10.2静态实例初始化
class Cup {
Cup(int marker) {
System.out.println("Cup(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}
class Cups {
static Cup c1;
static Cup c2;
static{
c1 = new Cup(1);
System.out.println("inside static");
c2 = new Cup(2);
}
Cup c3 = new Cup(3);
Cups(){
System.out.println("Cups()");
}
}
public class ExplicitStatic {
public static void main(String[] args) {
System.out.println("Inside main()");
Cups.c1.f(99);
Cups.c2.f(100);
new Cups();
}
}
结果:
Inside main()
Cup(1)
inside static
Cup(2)
f(99)
f(100)
Cup(3)
Cups();
解释:
静态变量只初始化一次
数据成员初始化在构造函数前 。
10.3 非静态实例初始化
class Mug {
Mug(int marker) {
System.out.println("Mug(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}
public class Mugs {
Mug c1;
Mug c2;
{
c1 = new Mug(1);
c2 = new Mug(2);
System.out.println("c1 & c2 initialized");
}
Mugs(){
System.out.println("Mugs()");
}
public static void main(String[] args) {
System.out.println("Inside main()");
Mugs x = new Mugs();
}
}
结果:
"Inside main()",
"Mug(1)",
"Mug(2)",
"c1 & c2 initialized",
"Mugs()"
解释: 看起来它与静态初始化子句一模一样,只不过少了static 关键字。这种语法对于支持“匿名”内部类的初始化是必须的。
多谢浏览 ,敬请斧正!