//常量:
用关键字final来表示常量(类似于const)
类常量:
用static final表示(加static是为了能被main调用)
//移位操作:
>>>是用0填充高位
>>是用符号位填充高位
//数据类型的缺省:
写小数是默认为double类型的,如果要float类型就在数字后面加f
写整数默认是int型,如果long后面叫l才行 (包括short类型和long类型)
//打印操作:
打印变量的时候 println(“型号:”+brand),自带换行功能
或者直接(brand),这里brand是一个初始化的字符型变量名
//数学函数:
如果要使用一个数学函数,不用先写他的类
sqrt(),处理的不是对象,是静态方法
pow函数是两个double类型的数据,所以返回的数值也是double类型的
Math.PI和Math.E是两个无理数的近似值
舍入操作【round返回的是long类型】:(用于从小数化成整数的情况):int nx = (int)Math.round(x); 强制类型转换中的舍入操作
括号与优先级:+=是右优先
1>
绝对值函数,可以有多种类型的绝对值函数,int、float【但是这个类型的数据要先在数据后面加一个L,来表示是long数据类型】
2>
上下取整函数public static double ceil(double d),【都是double类型的数据和结果】
*其实返回的是一个整数,但是存储在double类型的格式
3>
四舍五入函数: public static int round(float f)
public static long round(double d)
/如果两边距离不一样,就取距离近的那个数字
/如果是0.5,就去舍入后值大的那个数,-11.5变成-11
//子串:
String greeting = “Hello”;
String s = greeting.substring(0,3);
这个是从位置0 开始,不包括位置3的一段字符
//加号:
加号用于输出时拼接,好像也能用于字符串拼接:
1>
String str=String.format("%10d%d",20,30)类似的格式
2>
String a = “yinzhihan”; String b = “zhuida”;
String combined = a+b; (或者a直接就是“xin”)à其中a/b会自动转换为字符串
****也可以打印输出时直接使用printf,(不带换行功能)
//利用子串和加号修改字符串:
Stringa = “Hello!”;
a= a.substring(0,3)+”pp”; 结果就是Helpp
//但是其实是开了一个新的空间,将a指向这个空间
//如果要构建字符串,并且不停的添加:
StringBuilder builder = new StringBuilder();
builder.append(str);用来不停地添加字符串
//检测字符串是否相等:
String a ,b;
*a.equals(b);
如果相等返回True,如果不相等,返回False; 也可以“Hello”.equals(a);
也就是a可以是常量(”hello”)或者变量 *equalsIgnoreCase:不区分大小写比较
首字母:字母、下划线和$
中间内容:字母、下划线、$和数字
输入操作:Scanner x=new Scanner(System.in);这句话定义一个输入类型的变量
double y=x.nextDouble(); 这句话输入 【double类型】
string y=x.next()是只读到空格;nextline是读一行 【都是string】
//char类型的输入和代码单元:
输入char类型:char y= x.next().charAt(0); 【用代码单元函数读取char类型的数据】
String greeting = “Hello”;
Char first =greeting.charAt(0); 返回的值是H
Char last =greeting.charAt(4); 返回的值是o
***整形和浮点型自动化成浮点型
***强制类型转换(小类型到大类型):int
i=(int)x; 相较之下,自动类型转化是从大类型转化到小类型
***在一个类里面写函数,要写静态函数,因为main函数是静态main函数
高内聚,低耦合
//类是同种对象的集合:其中有对象的属性和操作对象属性的方法
***类当中声明时加了static的变量,是关于类的变量,没有static的变量是对象的变量
所有对象对于对象的变量有单独的空间进行存储,但是对于静态类变量,所有对象只有一个公共的空间
** 静态的只能访问静态的,但是实例化的能访问所有的
** 在类外面访问类变量,用类访问或者对象访问
重载:参数的个数,参数的顺序,参数的类型
*返回类型不是signature的一部分,不能有两个名字相同,
参数类型也相同,却返回不同类型值的方法。即不可以一个void,一个int //只是参数名字不一样不构成重载
//对象和引用:
举个例子,我们通常会用下面这一行代码来创建一个对象:
Person person = new Person(“张三”);
有人会说,这里的person是一个对象,是Person类的一个实例。
也有人会说,这里的person并不是真正的对象,而是指向所创建的对象的引用。
到底哪种说法是对的?我们先不急着纠结哪种说法是对的,再看两行代码:
Person person;
person = new Person(“张三”);
这两行代码实现的功能和上面的一行代码是完全一样的。大家都知道,在Java中new是用来在堆上创建对象用的,如果person是一个对象的话,那么第二行为何还要通过new来创建对象呢?由此可见,person并不是所创建的对象,是什么?上面的一段话说的很清楚,“操纵的标识符实际是指向一个对象的引用”,也就是说person是一个引用,是指向一个可以指向Person类的对象的引用。真正创建对象的语句是右边的new Person(“张三”);
//类的访问权限修饰符:
public类:不但可以被同一程序包中的其它类使用,别的 程序包中的类也可以使用. ?
friendly(缺省):类只能被本包中的其它类使用 ?
**var:任意格式,根据数据的具体类型再决定是什么类型
//变量和方法的修饰符:
Protected:同一类,同一包可以使用。不同包的类B要使用类A中的protected方法或者变量,必须满足 以下条件:
类A是可见的(public),类B是类A的子类。(继承类)
//代码点和代码单元:
\:辅助字符
\c: 是3个代码点,2个代码单元
// 一个.java文件里面,只能由一个访问权限为public的类
//源文件是.java 【就是程序员看得懂的语言】
但是编译之后是.class文件,存放在.bin里面【二进制文件】
//一个类里面可以有两个同名的变量名,但是相互区别或者覆盖
注意:是class里面的一个a,还是class里面方法的局部变量a (this可加可不加)
加了this.a就是指这个类里面的变量
***如果是static的方法,不能用this访问
//大数值:(3.9)
BigInterger
a = BigInterger.valueof(100); 用于将整形类型的数组转换成大数据类型
**但是大数据类型不能使用+ -,并且java没有加号重载,要进行加法只能
BigInterger c=a.add(b);
*并且如果要进行比较,只能使用compareto函数(这个函数还适用于String类型的数据)
// 数组:(java当中的数组都是指针,但是不可以通过数组名+1来访问数组)
----也因为是指针,所以int[ ]
a=b;(b一开始也是一个数组)会使得a和b指向同一个数组(指向一个地址空间),对a进行的操作,也就是对b进行相应的改变。
**创建一个数字数组时,所有元素都初始化为0;boolean会初始化为false;对象数组和字符串初始化为null
**数组的静态初始:int[ ] a={1,2,3,4};
动态初始化:
int[] intArray;//声明数组
intArray = new int[5];//为数组分配空间 【这种情况下都是指向空指针】
所谓的静态和动态是相对于程序运行是而言的,静态是在程序编译时就初始化好了的,动态初始化是在程序运行是才动态分配内存空间。对于代码而言,其实都可以。唯一不一样的地方, 就是动态的初始值都是0,静态的是直接给定值了。
**for each循环:
格式:for ( int element: a)
System.out.println(a[element]) //针对打印出每个数组元素
好处:不用下标就访问所有的数组元素
----有一个函数可以更快的返回一个包含一维数组元素的字符串:Array.toString(a)
二维数组元素的字符串:Array.deepToString(a);
**二维数组【i】【j】是一个有i个指针的指向长度为j的字符串的数组
//不同于真正的二维数组(指向i*j个元素)
—java允许数组长度为0,但是数组长度为0,与数组为null(空)不同
创建的时候: int[ ] a
={1,2,3,4};(可以不写new的一个简单写法)
****静态创建数组:
String first = “rose”;
String second = first;
first= “lily”;此时,first是lily,但是second还是rose(因为这句话执行的时候,给first分配了一个新的空间)
原因:字符串的只读性,不能进行更改
----StringBuffer声明一个字符串时,可以继续对这个字符串进行一系列操作,【修改增加时,就是在原来的空间进行修改】<->String不行(只读类型)
用于:循环的赋值、改变
(也因此,String类型的数据不能与StringBuff类型的数据划等号)
***同时:StringBuffer里面的equals和==一样,是位置的判断(继承了String,但是equal没有重写,所以是最初的等于号)
但是String里面的equals是判断内容是否相同
所以如果要比较两个stringbuffer类型的字符串大小,就要用toString方法先把他们转换成String类型的数据
----对String的修改,就是开辟了一个新的空间,产生了一个新的副本,原来的自动删除 【如果内容没有改变,就还是这个空间,没有开辟新的空间】
*****两个字符串进行比较,比较的是这两个字符串的地址空间是否相同(静态分配,和动态分配)
数组交换、排序,改变的是引用,每个数组的指向地址不改变;
**通常严谨的考虑:要考虑传入的数据是否有效(类似栈溢出的判断)
----数组复制:
1>
直接用等于号进行复制,是指针的复制
2>
使用Arraycopy,是开辟一个新的数组空间(还可以控制复制哪些内容)
–*****-- public String ToString ,调用这个类的时候,自动打印这个函数里面的语句
toString这个函数,是Object类自带的,在遇到println这类型的语句时,会自动调用;【一般建议重写,不重写的话要避免使用println(obj)这种语句,会输出XXX@xxx】
*–*好处就是打印的时候不用显式地调用这个语句
**如果打印数组的名称,打印出来的是数组的首地址
主要的为:
1>
Int
compareTo( String other) 用于比较字符串大小【返回的是从哪一个字母开始不相同,这两个字母之间相差的字母数】
2>
字符串转成字符数组toCharArray()
3>
Trim()函数去掉字符串前后的空格和各种回车,在字符串比较的时候很有用
62
//Date函数:
Date a = new
Date(); 默认当前时间
**Date a = new Date(long 数字);把a赋值为距离这个秒数的日期
----String b = new a.toString(); 把当前时间转换成字符串,最后输出
****实际代码段:(格式化输出,并且把格式改成String类型)
Date da = new Date();
SimpleDateFormat dat= new SimpleDateFormat("yyyyMMdd");
String date = dat.format(da); //从date变成字符串
Date tim=dat.parse(customer.getDate()); //从字符串变成date
long tie=(da.getTime()-tim.getTime())/(24*60*60*1000);
int time=(int)tie/365;
//初始化块:
-----类属性,在编译时会自动初始化,但是局部变量不会被初始化
br 为局部变量,line1 使用时没有初始化,编译时就出错。
ar 为属性,系统会进行初始化,ar 初始化为null ,最后输出为“null”
【也因此很多情况下,直接这样使用指针,会报错,空指针】
*******但是,如果是动态new一个数组,自动初始化
//继承:
子类对父类中方法和属性的继承,是由父类中各个方法和属性的访问权限来决定的。
->只有public ,protected ,default 的方法和属性子类才有可能继承,
private 的方法和属性是不能被继承的。
***子类可以对父类函数进行重写(父类的这个函数还是存在的,知识子类里面这个函数被重新改写了)或者是重载
----super关键字:
当父类的方法被子类覆盖的时候,如果需要重新调用父类的方法或者属性可以用
【所以在子类的重写print里面是可以调用父类里面的print,只要加上super;否则会循环调用子类自己的print函数】
-----在创建新的子类对象时:
首先调用父类的构造方法 super()(系统默认就会执行) 。【也就是说,在创建子类时,先会调用父类的构造函数,再是子类的构造函数,两句输出语句】
****父类一定要写没任何参数的构造函数,因为子类创建时就会调用这个构造函数,不写就会报错【要么父类加一个没有任何参数的构造函数,要么子类的构造函数第一句就调用父类有的构造函数,super(name_)】
子类里面定义了一个父类的对象,并且子类和父类不再一个包中,则是不能访问父类的protected函数的;
1> final 修饰方法:方法在继承过程中保持不变(只读),虽然能够被继承,但是不能被重写
2> final 修饰类:说明被声明的类不能够作为super class
3> 可以有很多儿子,但是只能有一个爸爸
-----向上转型(upcasting)
子类可以转换为父类,但是父类不一定可以转换为子类(儿子总会当爸爸)
Eg. p1=s1; //只是父类指向子类,不用强制类型转换
è 会导致接口窄化,因为继承之后,父类p1只能访问父类地方法,不能访问子类新增的方法,能访问的方法变少了【但是重写的方法,是指向孩子】
è 向上转型之后【前提是原来是子类】还能转成子类本身吗?
Answer : 可以的,在这种情况下向下转型是允许的,可以通过强制类型转换来现。
-----向上转型(casting)
Public static void main(String args[] ){
Person p = new Person();
Student s = new Student();
p.printName();
p = s // 父类指向子类,不用检查
p.printName();
if(p instanceof Student) //检查p是否为student的一个实例,是才能转换
【因为子类当中可能有父类不包括的方法,所以要先检查才能转化】
s = (Student)p; // 经过判断之后可以进行向下转型
}
-----动态绑定:
当我们用一个父类的引用指向子类的对象,【向上转型】同时用父类的引用调用在子类中被重写的方法的时候,编译器会为我们选择合适的子类中的方法然后执行,这就是动态绑定。【也就是说没被重写的话指向父类的函数】
****但是,如果是父类的static函数在子类中有一摸一样的一个static函数,则父类指向子类的时候,引用这个函数的时候,还是使用自己的函数,不使用子类的【也就是说不会动态绑定,是静态绑定】
private ,final 修饰,static 修饰的方法不能被Overriding, 所以这类方法也不会发生动态绑定。
static不会发生动态绑定现象
子类不能继承父类的static属性函数,但是可以访问
–**–子类和父类的static属性或者函数,就算重名,也是相互独立的,不存在多态性
Summary:
1> 子类自己没有构造方法,则它将继承父类的无参数构造方法作为自己的构造方法。
2> 如果子类自己定义了构造方法,在创建新对象时,将先调用父类的无参数构造方法,再执行自己的构造方法。
3> 父类包含参数的构造方法,则在子类构造方法中使用 super(variable )关键字来用它,这个调用语句必须是子类构造方法的第一条 语句
–**–关于对象数组的排序问题:
1> 利用comparable接口:
主要针对一个类当中一种排序【要么姓名排序,要么工资排序】
Eg.class goods implements Comparable<object>{
…各种相关的构造函数和方法
Public int compareTo(Object o){
Goods s = (Goods) o; //先是进行强制类型转换
if(this.price>s.price)return 1;
else return -1;
}}
【 在类当中直接写compareto函数,然后在main函数里面直接调用sort含糊是就可以按照事先写的进行排序 【object可以直接写成这个类名goods】
compareTo函数在接口中没定义成public,但是是默认为public的,在类里面实现的时候要写成public】
3> 利用Comparator接口:【可以实现多种不同的排序要求】
public void NameSort() {
//写在类当中作为一种排序的方法
Arrays.sort(Employees,0,count,new NameCmp()); //sort当中是由接口的一种特定排序方式
for(int i=0;i<count;++i) {
System.out.println(Employees[i].name+' '+Employees[i].salary);
}
}
class NameCmp implements Comparator<Employee> {
//为了支持sort而写的一种类
public int compare(Employee a,Employee b) {
if(a.name.compareTo(b.name)<0) return -1;
if(a.name.compareTo(b.name)==0) return 0;
else return 1;
}
}
//抽象函数,抽象类【不能实现方法】
public abstract class Solid {
public abstract double surfaceArea()
;
//括号中可以有参数,也可以没有参数
public abstract double volume() ;
}:
【因为越继承,越抽象,用Abstract可以使设计变得清晰】
1> 抽象类不能够实例化(不能拥有自己的抽象对象)
不支持通过构造方法创建新的对象
可以定义一个抽象类的引用
2> 包含抽象方法的类一定要被定义为抽象的
3> 抽象方法不能用private修饰
4> 除了抽象的方法之外,抽象类还可以包含非抽象的数据以及方法。
5> 一个抽象类(A )的所有的非抽象的后代都必须实现它(A )所定义的抽象方法。【如果是抽象的,就不用实现】
6> 一个类如果没有提供任何的抽象方法,也可以声明为抽象类。
******-----static方法里面不能加super,访问super的属性或者方法【因为static是这个类本身的属性】
//接口:
Interface是一个关键字,用来定义一个接口;或者用来写、创建一个接口
- 定义接口的时候可以加访问权限修饰符public 。默认是friendly 。访问效果和类的访问权限是相同,
e.g interface writeFile{ }
public interface writeFile{ }
-
接口中只是对方法的声明,没有方法的实现。
-
接口中不允许有静态的方法。
-
接口中的属性和方法只允许是public 的,如果不加任何的修饰符那么它们只会是public 的。
-
接口也可以继承,支持多重继承
Implements是用来实际使用某个接口时用的关键字,直接跟在类的后面
—à 可以实现多个接口,用逗号隔开就可以【一旦引入接口,接口当中的每个函数都要实现】
Eg. public int compareTo(Object b){ //【将object直接改成这个类的名字就不用强制类型转换】
Person p;
if(
b instanceof person){ //先类型转换
p = (person)b;
if(age > p.age)
return 1;
else
if(age == p.age)
return 0;
else
return -1;
}
}
//内部类:
Inner Class
:是一个被定义于另一个类中的类。
一个内部类的对象可以访问创建它的那个对象的成员。
同一包内,内部类可被其他类隐藏起来。
打算动态回调函数时,采用匿名内部类比较容易。
在编写事件驱动程序时,内部类非常方便。
Inner class 可以用private 来修饰。
Inner
class 出现的位置:
在一个class 的方法中。
在一个class 的方法外部。
**—**这两个类都会在硬盘上显示,内部类也有独立的地址空间;
----内部类引用的例子:
//【就是在引用内部类的时候先用外部类的构造函数,再使用内部类的构造函数】
MyOuter mo = new MyOuter();
MyOuter.MyInner inner = mo.new
MyInner();
inner.seeOuter();
MyOuter.MyInner inner = new MyOuter().new
MyInner();
inner.seeOuter();
这两段代码是一样的,一个是先定义了一个外部类,再通过访问内部类
***This单独输出的是当前类的地址
//匿名类:
匿名的inner class 表示方法为:
1.匿名的内部类不能有构造方法,因为没有类名所以没法定义构造方法。
2.匿名类在定义类的同时创建了对象,所以匿名类只对应一个对象。
//通过创建一个对象来实现匿名类
3.匿名类一般都是继承一个父类或者是实现一个接口。
如上例所示:
Class food{
Popcorn p = new Popcorn() {‘
public void pop() {
System.out.println(“anonymous
popcorn”);
}
};
该匿名类继承了父类Popcorn, 并且重写了父类中的pop() 方法
----匿名类实现一个接口:
class MyWonderfulClass {
void go() {
Bar b = new Bar();
b.doStuff(new Foo() {
public void foof() {
System.out.println(“foofy”);
} // end foof method
}); // end inner class def, arg, and end statement
} // end go()
} // end class
interface Foo {
void foof();
}
class Bar {
void doStuff(Foo
f) { }
}
*****interface和implements可以堪称是继承了一个接口函数,但是和extends不同的是:
在java中implements表示子类继承父类,如类A继承类B写成 class A
implements B{}
与Extends的不同
extends, 可以实现父类,也可以调用父类初始化
this.parent()。
而且会覆盖父类定义的变量或者函数。
这样的好处是:架构师定义好接口,让工程师实现就可以了。整个项目开发效率和开发成本大大降低。
implements,实现父类,子类不可以覆盖父类的方法或者变量。即使子类定义与父类相同的变量或者函数,也会被父类取代掉。
这两种实现的具体使用,是要看项目的实际情况,需要实现,不可以修改implements,只定义接口需要具体实现,或者可以被修改扩展性好,用extends。
可以用接口定义一个对象指向引入这个接口的类【因为implements类似于extends,不过implements只写不改】
//异常处理:
è Try里面有异常就走catch,finally是一定要被执行的【try当中是return也要执行finally】;
**string类型的非数字数据不能被转换成float类型的数据
–就算是数字类型的字符串,如果越界,也不能转换成int
除非异常类型和catch里面的异常类型相同,才会成功走异常处理;否则这一个异常处理无用
Catch里面写的是异常类 ,和异常类定义的形参【形参名无所谓】
1>
如果类型匹配成功,会执行catch里面的语句,和catch外面的语句,顺序执行完
2>
但是如果匹配失败,不会执行catch,不会执行catch外面的语句;直接从异常的这句话结束整个程序
3>
没有出现异常,会执行catch外面的语句,顺序执行完
直接在错误出现的语句结束
------系统的梳理:
一遇到错误语句就跳出try执行catch里面的语句【不论是否错误类型是否匹配】
为了处理更多可能的错误,一般使用Exception错误类【但是提供的信息比较少】
-----自己定义一个Exception类【必须继承Exception】
** Exception类:
public Exception()
public
Exception(String message)
//具体描述这个异常;用于getmessage里面返回的内容
还有getmessage和tostring和printstacktrace三个方法用来的到这个异常的具体信息
//throw语句
try {
throw new
NullPointerException(); //程序一执行到这句语句,遇到throw语句立刻结束,并且取catch进行匹配
}catch(NullPointerException e){
System.out.println("in
catch get exception: "+e.getMessage());
}
其中如果catch里面的错误类型和throw不相匹配,则直接执行finally里面的语句,再打印出throw的错误信息
—进一步说明,【当方法中含有throw语句】:
第一种方法: 在方法的内部异常出现的地方,即throw语句出现的地方,用try 语句捕获异常,catch 语句处理异常。(这个方法内部写try和catch)
第二种方法:
产生异常的方法不直接处理异常而是由调用该方法的其他方法来用try 和catch
程序块处理异常。(在调用这个函数的main函数加这个检查语句)
—自己定义一个异常类:
Public
class YourNewException extends Exception { }
//一定要继承,里面可以写任何内容
Eg. class
NotAValidAttribute extends Exception{
public NoValidAttribute (){}
public NoValidAttribute (String err){
super(err); //访问父亲类【Exception】的带参数的构造函数
}
}
----具体实现代码:
一般需要两步来Throw an Exception :
第一步:在method header 后首先定义方法中将要抛出的异常类型列表,即为throws list
第二步:在需要报告异常的程序部分创建相应的异常的实例并且throw 出该实例。
即为:throw instance
public void
setName(String n) throws
NotAValidAttribute {
if (n == null)
throw new NotAValidAttribute(“error: employee’s name is
null”);
else
name = n;
}
注意: 如果在throw 语句中用try
和catch 直接处理了异常,那么throws语句可以省略。
【就是如果程序中有处理这个异常的try和catch,就可以省略throws】
//文件操作:
1>把文件重命名并且移动存储的位置
File a = new File(“c:a.txt”);
File B = new File("d:b.txt);
//返回值为boolean类型
Boolean boolean = a.renameTo(B); //这句话使得
try {
// FileReader fr = newFileReader(“student1.txt”); //源文件
FileReader fr =
new FileReader("./src/student.txt");
//一定要是这个文件的物理路径
BufferedReader
br = new BufferedReader(fr); //缓存以增强效率
while((String
read = br.readLine())!= null)
System.out.println(read);
fr.close();
br.close();
} catch (IOException ie){
System.err.println(ie.getMessage());
}
}
StringTokenizer
st = new StringTokenizer(str,",");
//一个参数是字符串,一个是符号
—Properties类型:load,setproperties,getproperties
// 接口作为形参:
1、使用接口作为形参意味着可以使用这个接口的实现类的对象的引用作为实参传递给方法
2、可以传递null,但会报NullPointerException异常
Interface 不能够通过new 来创建自己的实例。但是
需要注意: 一个实现了接口的类的实例可以转型
为接口类型。
import java.io.*;
import java.io.FileReader;
import java.util.*;
interface Int{
void go();
}
class BB implements Int{
public void go() {
System.out.println("h");
}
}
class AA implements Int{
public void calls(BB b) {
b.go();
}
public void call(Int p) { //这个p最终传到这个函数里面的实参是包含Int这个 接口的类的对象
p.go();
}
@Override
public void go() {
// TODO Auto-generated method stub
}
}
public class try1 {
public static void main(String[] args) {
AA aa=new AA();
BB bb=new BB();
aa.calls(bb);
aa.call(bb); //bb就是实际传入到这个函数当中的参数
}
}
Arraylist定义一个数组链表,功能有add,size,remove
构造函数【无参数的函数,且函数名和类名相同】:可以返回不是void类型的结果