标签:变量 info lin 有助于 ima and 不同 整理 用两个
测试while
public class whileTest {
static boolean condition(){
boolean result = Math.random() < 0.99;
System.out.println(result + ",");
return result;
}
public static void main(String[] args) {
while (condition())
System.out.println("Inside ‘while‘");
System.out.println("Exited ‘while‘");
}
}
===============================================
true,
Inside ‘while‘
true,
Inside ‘while‘
true,
Inside ‘while‘
true,
Inside ‘while‘
false,
Exited ‘while‘
Math.random 随机生产 0 ---1 的数字
do - while 至少执行一次
for循环常用于计数任务
public class whileTest {
public static void main(String[] args) {
Random rand1 = new Random();
Random rand2 = new Random();
for(int i = 0; i < 5; i++) {
int x = rand1.nextInt();
int y = rand2.nextInt();
if(x < y) System.out.println(x + " < " + y);
else if(x > y) System.out.println(x + " > " + y);
else System.out.println(x + " = " + y);
}
Random rand3 = new Random();
Random rand4 = new Random();
for(int i = 0; i < 5; i++) {
int x = rand3.nextInt(10);
int y = rand4.nextInt(10);
if(x < y) System.out.println(x + " < " + y);
else if(x > y) System.out.println(x + " > " + y);
else System.out.println(x + " = " + y);
}
}
}
====================================================
-1636716208 < -1366578013
-630773338 > -1420580444
342336183 < 784053746
1142887002 > 325688001
-1102830792 > -1683393166
8 > 4
3 > 0
7 < 8
0 < 3
1 < 6
forseach
不必创建 int 变量 去对由其访问项构成的序列 进行计数
for (int i : range(10))
print(i+"");
===============
0 1 2 3 4 5 6 7 8 9
练习8
public class SwitchTest {
public static void main(String[] args) {
for(int i = 0; i < 11; i++) {
switch(i) {
case 0: print("zero"); break;
case 1: print("isa"); break;
case 2: print("dalawa"); break;
case 3: print("tatlo"); break;
case 4: print("apat"); break;
case 5: print("lima"); break;
case 6: print("anim"); break;
case 7: print("pito"); break;
case 8: print("walo"); break;
case 9: print("siyam"); break;
default: print("default");
}
}
}
}
======================================================
zero
isa
dalawa
isa
dalawa
dalawa
tatlo
apat
lima
anim
pito
walo
siyam
练习9
public class Fibonacci {
int fib(int n) {
if(n < 2) return 1;
return (fib(n - 2) + fib(n - 1));
}
public static void main(String[] args) {
Fibonacci f = new Fibonacci();
int k = Integer.parseInt(args[0]);
System.out.println("First " + k + " Fibonacci number(s): ");
for(int i = 0; i < k; i++)
System.out.println(f.fib(i));
}
}
==================================================
1
1
2
3
构造器 和 垃圾回收机制
? 可以假想为每一个类都定义了 initialize() 方法。通过构造器,确保每个类都被初始化了。创建对象时,如果其类具有构造器,Java就会在用户操作之前自动调用相应的构造器,从而保证了初始化。
构造器 与 类 同名, 方便计算机自动找到,而且不与自定义的属性或者方法重名。
构造器
练习1
lass Tester {
String s;
}
public class ConstructorTest {
public static void main(String[] args) {
Tester t = new Tester();
System.out.println(t.s);
}
}
=============================================
null
练习2
class Tester2{
String s1;
String s2 = "hello";
String s3 = "initialization by self";
Tester2(){
s3 = "constructor initialization";
}
}
public class ConstructorTest {
public static void main(String[] args) {
Tester2 t2 = new Tester2();
System.out.println("t2.s1="+ t2.s1);
System.out.println("t2.s2="+ t2.s2);
System.out.println("t2.s3="+ t2.s3);
}
}
=================================================
t2.s1=null
t2.s2=hello
t2.s3=constructor initnizetion
构造器初始化优先级高
名字
创建一个对象时,给对对象分配的存储空间取了一个名字
方法则是给某个动作取个名字
通过名字引用所有的对象和方法。
每一个方法都要有唯一的名称
? 假设你要创建一个类,既可以用标准方法初始化,也可以从文件里读取信息来初始化,这就需要两个构造器:一个默认构造器,一个取字符串作为形式参数----该字符串表示初始化方法对象所需要的文件名称。急类名。为了让方法名相同而形式参数不同的方法同时存在,必须用到方法的重载。
区分方法的重载 其实很简单,
每个重载的方法都必须有第一无二的参数列表。
参数的顺序也可以把他们区分开来
没有形式参数,创建一个“默认对象”。如果你写的类中没有构造器,则编译器会自动帮你创建一个默认构造方法。
练习3
class Kabayo{
Kabayo(){
System.out.println(" is a Constructor");
}
}
public class DefaultConstructorTest {
public static void main(String[] args) {
Kabayo k = new Kabayo();
}
}
======================================
is a Constructor
如果 只有 一个 Peel 方法,创建了一个对象 a,一个对象 b.
a.peel(1);
b.peel(2);
它是被a调用了 还是 b呢?
编译器 暗自中 把 所操作对象的引用 作为 参数传递给 peel() 内部表示形式
peel(a,1);
peel(b,1);
在方法内部获得对当前对象的引用, 当前对象 : 调用这个方法的对象。 this
this 值调用方法的那个对象的引用 a b
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();
}
}
==========================================================
3
由于 increment()通过this 关键字返回了对当前对象的引用,所以很容易在一条语句里对同一个对象执行多次操作。
练习8
public class Doc {
public static void main(String[] args) {
new Doc1().intubate();
}
}
class Doc1{
void intubate() {
System.out.println("prepare patient");
laryngoscopy();
this.laryngoscopy();
}
void laryngoscopy() {
System.out.println("use laryngoscope");
}
}
===================================================
prepare patient
use laryngoscope
use laryngoscope
一个类中写了多个构造器,有时可能想在一个构造器中调用另一个构造器,避免代码重复 可以用this
This 表示 这个对象 或者 当前对象,而它本身代表当前地下的引用。
this 添加了参数列表,对符合此参数列表的某个构造器的明确调用
static 就是没有 this的 方法
垃圾 回收 只知道释放哪些经由 new分配的内存
为了释放 那些 不由 new 分配的内存,允许在 类中定义 finalize()方法。
finalize
无论对象时如何创建的 ,垃圾回收器都会负责释放对象所占据的所有内存。所以 finalize之所以要用 ,是因为在分配内存时候可能用到了 本地方法 的情况 本地方法目前只支持 c 和 c++
也许调用了 c 的 malloc()函数 系列 来分配存储空间。而且除非用 free()函数 来释放 空间 否则 得不到释放
如果JVM 虚拟机 并未 面临内存耗尽的情况 是不会浪费实际去执行 垃圾回收 回复内存的
练习10
class WebBank{
boolean loggedIn = false;
WebBank(boolean logStatus){
loggedIn = logStatus;
}
void logIn(){
loggedIn = true;
}
void logOut(){
loggedIn = false;
}
protected void finalize(){
if (loggedIn)
System.out.println("Error : still logged in");
}
}
public class TerminationConditionEx {
public static void main(String[] args) {
WebBank bank2 = new WebBank(true); // 定义出来不用 垃圾回收自动清理
bank1.logOut();
new WebBank(true); // 一直new 一个 对象 ,一直得不到清理。调用 fianlize方法 检查 验证终结条件
System.gc();
}
}
==========================================================
Error : still logged in
练习11
class Webbank {
boolean loggedIn = false;
Webbank(boolean logStatus) {
loggedIn = logStatus;
}
void logOut() {
loggedIn = false;
}
protected void finalize() {
if(loggedIn)
System.out.println("Error: still logged in");
// Normally, you‘ll also call the base-class version:
// super.finalize();
}
}
public class BankTest {
public static void main(String[] args) {
Webbank bank1 = new Webbank(true);
Webbank bank2 = new Webbank(true);//垃圾回收自动清除
new Webbank(true); // 添加未被处理对象
// Proper cleanup: log out of bank1 before going home:
bank1.logOut(); // bank1 对象 被清理
// Forget to logout of bank2 and unnamed new bank
// Attempts to finalize any missed banks:
System.out.println("Try 1: ");
System.runFinalization();
System.out.println("Try 2: ");
Runtime.getRuntime().runFinalization();
System.out.println("Try 3: ");
System.gc();
System.out.println("Try 4: ");
// using deprecated since 1.1 method:
System.runFinalizersOnExit(true);
}
}
=======================================================================
练习12
class Tank{
int howFull = 0;
Tank(){this(0);}
Tank(int fullness){
howFull = fullness;
}
void sayHowFull(){
if(howFull == 0) System.out.println("Tank is empty");
else System.out.println("Tank filling status =" + howFull);
}
void empy(){
howFull = 0;
}
protected void finalize(){
if(howFull == 0)
System.out.println("Error:Tank is empty");
}
}
public class TankTest {
public static void main(String[] args) {
Tank tank1 = new Tank();
Tank tank2 = new Tank(3);
Tank tank3 = new Tank(5);
tank2.empy();
new Tank(6);
System.out.println("Check tanks:");
System.out.println("tank1:");
tank1.sayHowFull();
System.out.println("tank2:");
tank2.sayHowFull();
System.out.println("tank3:");
tank3.sayHowFull();
System.out.println("first forced gc():");
System.gc();
System.out.println("try deprecated runFinalizersOnExit(true):");
System.runFinalizersOnExit(true);
System.out.println("last force gc():");
System.gc();
}
}
Check tanks:
tank1:
Tank is empty
tank2:
Tank is empty
tank3:
Tank filling status =5
first forced gc():
try deprecated runFinalizersOnExit(true):
last force gc():
Error:Tank is empty
Error:Tank is empty
垃圾回收对与提高对象的创建速度有明显的效果。 存储空间的释放竟然会影响存储空间的分配
Java中 堆的实现 像一个传送带,每分配一个内存,它就前进一格。 对象在存储空间的分配速度非常快。Java的堆指针只是简单的移动到尚未分配的区域。但不是单纯的像传送带一样,垃圾回收的介入,在分配内存的同时,也释放前面已经分配好的内存,堆指针可以指向释放的区域,使得对象紧凑排列。
如何找到活着的对象(不同的Java虚拟机 实现不同)
JVM 有 许多 附加技术 用来 提升速度
例子:
? 当 加载 一个 类库时候(通常时该类创建第一个对象),编译器会找到 .class文件,然后将该类的 字节码 装入内存。
两种方案:
Java 尽力 保证: 所有的 成员变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时的错误来贯彻这种保证
可以用 构造 来初始化。 无法阻止 自动 初始化 的 进行,他将在构造器被调用之前发生
变量 定义的先后顺序 决定了 初始化的先后顺序。即使变量定义散步于方法定义之间,他们仍然会在任何方法(包括构造器)被调用之前得到初始化。
? 无论建立多少个对象,静态数据都只占一份 存储区域。static 不能应用与局部变量,因此它只能作用 于 域。
Java 允许 将多个静态初始化 组织 成 一个 “静态块”
这段代码仅执行一次 :当首次生成 这个类的 一个对象时,或者首次访问 属于那个类的静态数据 成员时
练习 14
class Go {
static String s1 = "run";
static String s2, s3;
static {
s2 = "drive car";
s3 = "fly plane";
System.out.println("s2 & s3 initialized");
}
static void how() {
System.out.println(s1 + " or " + s2 + " or " + s3);
}
Go() {
System.out.println("Go()"); }
}
public class ExplicitStaticEx {
public static void main(String[] args) {
System.out.println(g1.s1);
System.out.println("Inside main()");
Go.how();
System.out.println("Go.s1: " + Go.s1);
}
static Go g1 = new Go();
static Go g2 = new Go();
}
================================================
s2 & s3 initialized
Go()
Go()
run
Inside main()
run or drive car or fly plane
Go.s1: run
Java 中也有 实例初始化 的类似语法, 用来初始化每个对象的非静态变量。
练习 15
class Test {
String s;
{
s = "Initializing string in Tester";
System.out.println(s);
}
Test() {
System.out.println("Tester()");
}
}
public class InstanceClauseTest {
public static void main(String[] args) {
new Test();
}
}
====================================================
Initializing string in Tester
Tester()
int[] a
定义的时候 初始化
int[] a = new int[rand.nextInt(20)]
a[i] = rand.nextInt(500);
也可以用花括号括起来 的 列表 来 初始化 对象数组。 有两种形式
Integer[] a = {
new Integer(1),
new Integer(2),
3, // autoboxing自动封装
}
Integer[] b = new Integer[]{
new Integer(1),
new Integer(2),
3, //autoboxing
}
创建一个引用数组, 创建一个对象 并把对象赋值给引用 才算初始化进程结束
练习16
public class StringArrays {
public static void main(String[] args) {
String[] s = { "one", "two", "three", };
for(int i = 0; i < s.length; i++)
System.out.println("s[" + i + "] = " + s[i]);
}
}
练习17
class InitTest {
InitTest(String s) {
System.out.println("InitTest()");
System.out.println(s);
}
}
public class InitTest17 {
public static void main(String[] args) {
InitTest[] it = new InitTest[10];
}
}
什么都没打印
练习18
class InitTest {
InitTest(String s) {
System.out.println("InitTest()");
System.out.println(s);
}
}
public class InitTest18 {
public static void main(String[] args) {
InitTest[] it = new InitTest[5];
for(int i = 0; i < it.length; i++)
it[i] = new InitTest(Integer.toString(i));
}
}
===========================================================
InitTest()
0
InitTest()
1
InitTest()
2
InitTest()
3
InitTest()
4
可以 应用于 参数个数 或者 类型 未知 的 场合。
由于所有的类都直接或者间接继承object类,所以可以 创建 以 object 数组 为参数的方法。
**有了 可变参数 编译器 就再也不哟个 显示的编写 数组 语法了,当你 指定参数时,编译器 实际上会为你填充参数 如果你有了 一组事物 你可以把他们当作列表传递 而如果你已经有了一个数组 该方法可以把它们当作 可变参数列表传递 **
当有 可选的 尾随(trailing) 参数 这一方法 就会很好用
可变参数 列表为 数组的情况 如果没有 元素 数组尺寸为 0
可变参数 列表 可以 于 自动包装机制 和谐相处
可变参数列表 使 重载 变得 复杂了
每种情况下,编译器都会自动包装机制来匹配重载方法,然后匹配最明确的方法
在不使用 参数调用 f() 时 编译器 就不知道 调用那个方法了
可以 增加一个非 可变参数来 解决
练习19
public class InitTest19 {
static void showStrings(String... args) {
for(String s : args)
System.out.print(s + " ");
System.out.println();
}
public static void main(String[] args) {
showStrings("one", "TWO", "three", "four");
showStrings(new String[]{"1", "2", "3", "4"});
}
}
===========================================================
one TWO three four
1 2 3 4
练习 20
public class VarargEx20 {
public static void main(String... args) {
for(String s : args)
System.out.print(s + " ");
System.out.println();
}
}
enum 关键字
enum 可以和 switch 组合
练习 21
public class EnumEx21 {
public enum Bills {
ONE, FIVE, TEN, TWENTY, FIFTY, HUNDRED
}
public static void main(String[] args) {
for(Bills b : Bills.values())
System.out.println(b + ", ordinal " + b.ordinal());
}
}
===================================================================
ONE, ordinal 0
FIVE, ordinal 1
TEN, ordinal 2
TWENTY, ordinal 3
FIFTY, ordinal 4
HUNDRED, ordinal 5
练习 21
enum Bills {
ONE, FIVE, TEN, TWENTY, FIFTY, HUNDRED
}
public class Wallet {
Bills b;
public static void main(String[] args) {
for(Bills b : Bills.values()) {
System.out.print("Worth: ");
switch(b) {
case ONE: System.out.println("$1"); break;
case FIVE: System.out.println("$5"); break;
case TEN: System.out.println("$10"); break;
case TWENTY: System.out.println("$20"); break;
case FIFTY: System.out.println("$50"); break;
case HUNDRED: System.out.println("$100"); break;
default: break;
}
}
}
}
=====================================================================
Worth: $1
Worth: $5
Worth: $10
Worth: $20
Worth: $50
Worth: $100
标签:变量 info lin 有助于 ima and 不同 整理 用两个
原文地址:https://www.cnblogs.com/AronJudge/p/14336203.html