1.键盘录入中:
a.对于next和nextLine:
next语句遇到空格,回车(Enter),Tab键都会停止录入。
nextLine语句只有遇到回车(Enter)才会停止录入。
nextLine语句只能用于字符串录入
b.带有has的录入:返回值类型为布尔类型,例如boolean flag=it.hasNext();
c.static修饰键盘录入:
对于键盘录入时,会用到一个类Scanner->若一个方法中要用到类Scanner,则需要创建一次类Scanner对象;
若多个方法中要用到类Scanner,则需要每个方法中各创建一个类Scanner对象,
此时较麻烦,为了省内存,可把类Scanner写在类中方法外,用static修饰,归属于全类,这样就不需要多个方法中用到类Scanner时,每个方法中都创建一次类Scanner对象。
如下图:
2.全局变量和局部变量:
a.全局变量可以不赋初值,在对应方法内使用不报错;
b.局部变量如int a;,若之后没用到a,则int a;不报错,
若用到a,则int a;报错,此时需要为a赋初值,如int a=0;
3.异常:
a.源码:
NullPointerException类里有两个构造方法,第二个构造方法可以传字符串,比如写一些异常的内容。
RuntimeException类里也有两个构造方法,第二个构造方法可以传字符串,比如写一些异常的内容。
b.打印差异:
用printStackTrace方法会先把异常打印出来再执行第10行和第16行的语句。
会先把异常打印出来是因为ArrayIndexOutOfBoundsException不是自定义异常,所以会这样,
如果改用自定义异常就能够顺序打出:
如:
package a26practice;
public class Test {
public static void main(String[] args) {
Student s=new Student();
try {
s.setAge(-1);
} catch (AgeException e) {
System.out.println("---------------1");//先运行
e.printStackTrace();
/*运行结果为
---------------1
a26practice.AgeException: 年龄是非负的
at a26practice.Student.setAge(Test.java:20)
at a26practice.Test.main(Test.java:7)
*/
}
}
}
class Student{
private int age;
public void setAge(int age) throws AgeException{
if(age<0){
throw new AgeException("年龄是非负的");
}
this.age=age;
}
}
class AgeException extends RuntimeException{
public AgeException(){}
public AgeException(String message){
super(message);
}
}
第9行和第17行改用System.out.println(e);则会顺序打出。
4.继承关系:
a.实例:
测试类:
javabean类:
注:调用父类某个成员变量时该成员变量不能用private修饰
super.num=1相当于调用父类的成员变量num,此时父类中num为1,因此第七行输出语句中super.num即再次调用父类num时此时num为1。->尽管num在父类中是全局变量,但不是默认值0。
第七行输出语句中super.num换成num也许, 第六行super.num=1相当于调用父类的成员变量num,此时父类中num为1,
第七行此时为num时遵循就近原则,先在本方法中找,发现没有,再在本类方法外找,发现也没有,最后到父类中找,发现找到了num,此时num为1,输出结果为1。
运行结果为:
b.构造方法:
1.子类即使没有写构造方法,也会有个无参数的默认构造方法(前提是没写别的构造方法),仍然会调用父类的构造方法(super()默认在子类无参构造第一行,调用父类无参构造)
2.构造方法不会被继承。
c.子类继承下来的方法(即父类中非private,非static,非final的方法)只能操作子类继承了父类的
成员变量,也能操作父类中被隐藏的成员变量。
d.子类重写或者新增的方法*不能直接操作*被子类隐藏的成员变量(被隐藏的成员变量是指父类中)。
e.上转型对象不能操作子类新增的成员变量和方法,只有上转型类对象可以强制转换为子类对象
(父类对象不能强制转换为子类对象)
上转型类对象:父类 命名=new 子类();
父类对象:父类 命名=new 父类();
f.子类重写父类方法后,子类对象的上转型对象访问的是子类重写后的方法。
(虽然先加载父类,但之后也会加载子类,如果有方法重写,父类的方法会被隐藏,则访问子类的方法)
g.不可以将父类对象的引用直接赋值给子类对象,
但可以将子类对象的引用直接赋值给父类对象;
package a23practice;
public class Test {
public static void main(String[] args) {
Zi z=new Zi();
Fu f=z;//------------>可以将子类对象的引用直接赋值给子父类对象
/*Fu f=new Fu();
Zi z=f;-------->不可以将父类对象的引用直接赋值给子类对象
Fu f=new Zi();-->向上转型
Zi z=f;----------->不可以将父类对象的引用直接赋值给子类对象
*/
}
}
class Fu{
Fu(){}
}
class Zi extends Fu{
Zi(){
super();
}
}
h.举例:
例一:
package a24practice;
public class Test {
public static void main(String[] args) {
B b=new B();
//b.money=200;-->private修饰了money,不能继承给B,B访问不了money
//b.height=1.78f;-->height非私有,可以访问,但height是int型,不能用float型赋值
}
}
class A{
private int money=12;
float height;
int seeMoney(){
return money;
}
}
class B extends A{
int height;
int lookMoney(){
int m=seeMoney();
return m;
}
}
例二:
package a24practice;
public class Test {
public static void main(String[] args) {
A.f();
}
}
class A{
static int m;
static void f(){
m=20;
System.out.println(m);
}
}
class B extends A{
/*void f(){ -------->有误,静态方法不能被重写
m=222;
System.out.println(m);
}*/
}
例三:
class A{
public float getNum(){
return 3.6f;
}
}
class B extends A{
/*public void getNum(){} -->构成了方法重写,因为方法名和参数列表相同,但仍旧不对,
因为返回值类型也需要相同->改成public float getNum(){ 方法体 }即可 */
/*public void getNum(double d){} -->构成方法重载
public double getNum(float d){ return 4.2; } -->构成方法重载
public float getNum(){ return 5.6f; } -->构成方法重写*/
}
例四:
package a24practice;
public class Test {
public static void main(String[] args) {
B b=new B(100);
System.out.println(b.i);//运行结果为2
/* b.i即调用了B的构造方法,此时i为2,输出2->B中有i这个变量,从A继承下来的(i在A中非私有),
i在B类中是局部变量
*/
}
}
class A{
public int i=0;
A(){
i=1;
}
}
class B extends A{
B(int m){
i=2;
}
}
例五:
package a24practice;
public class Test {
public static void main(String[] args) {
B b=new B();
/* 无论子父类,只要出现了方法重载,会优先调用数据类型一致的方法*/
System.out.println(b.f(3,5));//运行结果为15.0
/* 3和5是整型,会调用B类里的f方法,由于返回值为double型,故结果为15.0 */
System.out.println(b.f(3.0,5.0));//运行结果为8.0
/* 3.0和5.0是浮点型,会调用A类里的f方法,由于返回值为double型,故结果为8.0 */
}
}
class A{
double f(double x,double y){
return x+y;
}
}
class B extends A{
double f(int x,int y){
return x*y;
}
}
例六:
package a24practice;
public class Test {
public static void main(String[] args) {
A a=new A();
System.out.println(a.getNum(10));//运行结果为30
//创建A对象,再调用A里的getNum方法
a=new B();
System.out.println(a.getNum(10));//运行结果为200
//子类对象的引用直接赋值给父类对象,B类重写了A类的getNum方法
//此时隐藏了A类的getNum方法,用的是B类的getNum方法
}
}
class A{
int getNum(int a){
return a+20;
}
}
class B extends A{
@Override
int getNum(int b){ //-->方法重写
return b*20;
}
}
例七:
package a24practice;
public class Test {
public static void main(String[] args) {
B b=new B();//创建了一个B类对象
System.out.println(b.f(10.0,8.0));//运行结果为98.0
/*调用B类的f方法,super.f相当于调用父类(A类)的f方法,得出m为18.0
则m+x*y=18.0+10.0*8.0=98.0(方法返回值为double型)
*/
System.out.println(b.g(3));//运行结果为12
/*调用B类的g方法,A.g(3)即调用A类的g方法,参数为3-->m=3*3=9
m+n=9+3=12
*/
A a=new B();
System.out.println(a.f(10.0,8.0));//运行结果为98.0
/*此时为上转型对象,子类B类重写了A类的f方法,隐藏了A类的f方法,则
用的是B类的f方法,
-->调用B类的f方法,super.f相当于调用父类(A类)的f方法,得出m为18
则m+x*y=18+10.0*8.0=98.0(方法返回值为double型)
*/
System.out.println(a.g(3));//运行结果为9
/* g为静态方法,a.g即类名.方法名调用了A类的g方法,结果为9
*/
}
}
class A{
double f(double x,double y){
return x+y;
}
static int g(int n){
return n*n;
}
/*static {
方法体
} -->这样的静态代码块运行一次后消失,而静态方法和静态变量不会运行后就消失
*/
}
class B extends A{
double f(double x,double y){ //-->重写了A类的f方法
double m=super.f(x,y);
return m+x*y;
}
static int g(int n){
int m=A.g(n);//g方法被static修饰,可类名.方法名去调用
return m+n;
}
}
例八:
package a24practice;
public class Test {
public static void main(String[] args) {
B b = new B();
b.m = 20;//此时B类中的m为20
System.out.println(b.getM());//运行结果为120
//调用B类的getM()方法可得结果为120
A a = b;
a.m = -100;//此时A类中的m为-100
System.out.println(a.getM());//运行结果为120
/*A a = b;为上转型对象,B类中重写了父类(A类)的getM()方法,则此时用的是B类的getM()方法,
而B类中的m仍旧为20(只是A类的m为-100),返回m+100=120-->a.getM()为120
*/
System.out.println(b.seeM());//运行结果为-100
/* b的类型为B类,调用的seeM()方法是A类继承下来的,此时A类中m为-100,seeM()方法返回-100,
b.seeM()结果为-100
*/
}
}
class A {
int m;//非私有
int getM() {
return m;
}
int seeM() {
return m;
}
}
class B extends A {
int m;//非私有
int getM() {
return m + 100;
}
}
5.多态:
a.强制类型转换-->模式变量
方法一:
方法二:使用模式变量
b.实现多态的三个必要条件:
one.继承-->有父子关系,才能看出父多了几个子
two.重写-->为了看出子类特有
three.父类引用指向子类对象即向上转型
c.instanceof关键字:
如C是B的子类,B是A的子类,c是C的对象,b是B的对象
则c instanceof B结果为true,因为c是B的子类
c instanceof A结果为true,因为c是A的子类
b instanceof C结果为false,因为b不是C的子类
6.异常:
a. 抛出RuntimeException异常会以红色文字打印在控制台。
b. finally关键字以及多重catch语句中,异常处理的顺序:
在Java中,多重`catch`语句用于捕获不同类型的异常。当使用多重`catch`语句时,异常处理的顺序是非常重要的,因为它决定了哪个`catch`块会处理抛出的异常。
以下是处理多重catch
语句中异常顺序的规则:
-
子类异常在前,父类异常在后:如果一个异常类是另一个异常类的子类,那么子类异常的
catch
块应该放在父类异常的catch
块之前。这是因为子类异常会在父类异常之前被匹配。如果父类异常的catch
块在子类异常之前,那么子类异常将永远不会被捕获,因为父类异常会先捕获所有异常。
例如,IOException
是Exception
的子类,因此如果你同时处理这两种异常,IOException
的catch
块应该放在Exception
的catch
块之前。
try { // 可能抛出异常的代码 } catch (IOException e) { // 处理IOException } catch (Exception e) { // 处理其他Exception }
2.具体异常在前,通用异常在后:更具体的异常应该首先被处理,然后是更通用的异常。这遵 循了“最具体优先”的原则。
3.finally块总是最后执行:无论是否捕获到异常,finally
块中的代码总是会执行(除非在try
或catch
块中使用了System.exit()
或其他方式终止了程序)。finally
块用于执行必须执行的清理操作,如关闭资源等。
注意:虽然Java允许使用多重catch
语句,但过多的catch
块可能会使代码难以阅读和维护。通常,最好只捕获你能够合理处理的异常,并允许其他异常冒泡到更高的调用栈级别。
最后,请确保你的代码适当地处理异常,避免忽略它们或仅仅打印堆栈跟踪。合理的异常处理是编写健壮和可靠代码的关键部分。
c.利用throws声明异常类型的意义:
在Java中,使用`throws`关键字声明异常类型的主要意义在于:
-
明确异常传播:通过
throws
声明,方法可以向其调用者表明它可能会抛出哪些类型的异常。这允许调用者知道在调用该方法时可能需要处理哪些异常,从而确保程序的健壮性。 -
异常链的传递:如果一个方法内部调用了其他可能抛出异常的方法,并且该方法不想或不能处理这些异常,那么它可以使用
throws
关键字将这些异常声明出来,以便其调用者可以处理它们。这有助于构建异常处理的层次结构,确保异常能够在适当的层次得到处理。 -
分离异常处理逻辑:通过将异常声明为
throws
,方法可以将异常处理的逻辑与其核心功能分离。这有助于保持方法的简洁和专注于其主要职责,而将异常处理的责任交给调用者。 -
强制调用者处理异常:如果方法使用
throws
声明了异常,那么任何调用该方法的代码都必须处理这些异常,要么通过try-catch
块捕获并处理它们,要么通过在其方法签名中也使用throws
关键字将它们继续向上层传播。这有助于确保不会忽略潜在的错误情况。 -
文档化可能的异常:
throws
声明也是JavaDoc的一部分,因此它们也可以作为方法文档的一部分,告诉开发者该方法可能会抛出哪些类型的异常。这对于理解和使用API非常有帮助。
需要注意的是,使用throws
声明异常并不意味着异常会被自动抛出。它只是表明方法可能会抛出这些异常,而实际是否抛出异常取决于方法内部的代码执行情况。同时,滥用throws
可能会导致异常处理的责任被过度推给上层调用者,从而增加代码的复杂性和维护成本。因此,在使用throws
声明异常时应该谨慎并考虑清晰的异常处理策略。
d.异常机制在实际项目中的应用:
Java中的异常机制在实际项目中扮演着至关重要的角色。它提供了一种识别及响应错误的一致性机制,使得程序在遭遇异常情况时能够优雅地处理,避免程序崩溃或数据丢失等不可预料的问题。以下是异常机制在实际项目中的一些主要应用:
-
提高程序的稳定性和可靠性:通过添加异常处理代码,程序能够在遇到异常情况时做出适当的响应,而不是简单地崩溃。这有助于确保程序的稳定运行,并减少数据丢失或损坏的风险。
-
提高程序的可读性和可维护性:异常处理机制使得代码更加清晰和易于理解。通过将异常处理代码与正常业务代码分离,可以使代码结构更加整洁,并方便后续的维护和升级。
-
方便程序的调试和排错:异常处理机制可以帮助程序员快速定位程序中出现问题的位置和原因。通过捕获和处理异常,程序员可以更容易地找到并修复代码中的错误。
-
提高程序的安全性:通过对可能出现的异常进行处理,可以有效地防止程序被恶意攻击或非法操作所破坏。异常处理机制可以帮助识别并应对潜在的安全威胁,提高程序的安全性。
在实际项目中,异常处理通常需要根据具体需求和场景进行定制。程序员需要仔细分析可能出现的异常情况,并选择合适的异常处理策略。这包括使用try-catch
语句块捕获和处理异常,以及使用throws
关键字声明可能抛出的异常类型。
此外,异常链处理机制在实际项目中也非常有用。通过将多个异常的信息串联起来形成一个完整的异常栈,可以提高错误信息的可读性,降低代码维护成本,并有助于开发人员逐步追踪到问题的根源。
总之,Java的异常机制在实际项目中发挥着重要的作用,它提高了程序的稳定性、可靠性、可读性和可维护性,并方便了程序的调试和排错。合理地使用异常处理机制可以使程序更加健壮和安全。
e. catch模块在一个try...catch语句中执行一次或者0次
f. 异常关键字的作用:
catch模块***用来捕获异常和处理异常
throw模块用来手动抛出异常
try模块*放入可能发生异常的代码*
throws模块用来声明异常
7.集合:
a.总结Collection:
b.List系列集合有关删除的操作:
package com.itheima.a02myList;
import java.util.ArrayList;
import java.util.List;
public class A02_ListDemo2 {
public static void main(String[] args) {
//List系列集合中的两个删除的方法
//1.直接删除元素
//2.通过索引进行删除
//1.创建集合并添加元素
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//2.删除元素
//这个删除的是1索引上的元素2,不是元素1
/*原因:在调用方法的时候,如果方法出现了重载现象
会优先调用实参与形参类型一致的那个方法
*/
list.remove(1);//方法提示中remove(int index)
System.out.println(list);//运行结果为[1, 3]
}
}
package com.itheima.a02myList;
import java.util.ArrayList;
import java.util.List;
public class A02_ListDemo2 {
public static void main(String[] args) {
//List系列集合中的两个删除的方法
//1.直接删除元素
//2.通过索引进行删除
//1.创建集合并添加元素
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//2.删除元素
//删除元素1的方法
//法一:list.remove(1);
/*法二:
手动装箱,手动把基本数据类型的1变成Integer类型*/
Integer i = Integer.valueOf(1);
list.remove(i);//此时删除的是元素1
//方法提示中是remove(Object o)
/*原因:在调用方法的时候,如果方法出现了重载现象
会优先调用实参与形参类型一致的那个方法*/
System.out.println(list);//运行结果为[2, 3]
}
}
8.静态:
a.静态代码块运行过程:
执行顺序: 父类静态代码块和静态成员变量->子类静态代码块和静态成员变量->父类普通代码块和普通成员变量->父类构造函数->子类普通代码块和普通成员变量->子类构造函数
(总结:先父类再子类,先静态再普通。静态代码块无论父子类,都先运行)
举例:
package a21practice;
public class B extends Object{
static {
System.out.println("Load B");
}
public B(){
System.out.println("Create B");
}
}
package a21practice;
public class A extends B{
static {
System.out.println("Load A");
}
public A(){
System.out.println("Create A");
}
}
package a21practice;
public class Testclass {
public static void main(String[] args) {
new A();
}
}
运行结果:
分析:
new了一个A对象,那么就要执行A类的构造方法来初始化对象,但是A类继承了B类,所以要先调用B类的无参构造;在A和B类中都有静态代码块,静态代码块是在加载类的时候进行执行,并且只执行一次,也就是说静态代码块在构造方法前进行执行,所以执行顺序是先执行B类的静态代码块,再执行A类的静态代码块,再执行B类的无参构造,最后执行子类的无参构造。
9.接口:
a.接口的继承:
接口继承的时候只能继承接口不能继承类,因为如果类可以存在非抽象的成员,如果接口继承了该类,那么接口必定从类中也继承了这些非抽象成员,这就和接口的定义相互矛盾,所以接口继承时只能继承接口。
b.接口的多继承:
接口可以多继承可以被多实现,因为接口中的方法都是抽象的,这些方法都被实现的类所实现,即使多个父接口中有同名的方法,在调用这些方法时调用的子类中被实现的方法,不存在歧义;同时,接口中只有静态的常量,但是由于静态变量是在编译期决定调用关系的,即使存在一定的冲突也会在编译时提示出错;而引用静态变量一般直接使用类名或接口名,从而避免产生歧义,因此也不存在多继承的第一个缺点。 对于一个接口继承多个父接口的情况也一样不存在这些缺点。所以接口可以多继承。
c.接口ListIterator,继承Iterator(迭代器):
hasNext方法和next方法结合能正向遍历集合,遍历后指针不会复位,此时可利用
hasPrevious方法和previous方法结合反向遍历集合。
迭代器创建后指针默认指向0索引。
d.接口类似类,可以创建对象,继承(接口只能继承接口)等。
10.遍历:
a.遍历结果差异:
package com.itheima.a02myList;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class A03_ListDemo3 {
public static void main(String[] args) {
//创建集合并添加元素
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//列表迭代器遍历
//获取一个列表迭代器对象,该列表迭代器里面的指针默认指向0索引
//当中额外添加了一个方法:在遍历的过程中,可以添加元素->不能用add即集合添加元素的方法
//只能用迭代器自身拥有的添加元素的方法->用迭代器调用
ListIterator<String> it = list.listIterator();
while (it.hasNext()){
String s=it.next();
if("bbb".equals(s)){
//此时添加qqq
it.add("qqq");//不能用集合添加即list.add("qqq");
}
}
System.out.println(list);//循环外再打印,运行结果为[aaa, bbb, qqq, ccc]
}
}
package com.itheima.a02myList;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class A03_ListDemo3 {
public static void main(String[] args) {
//创建集合并添加元素
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//列表迭代器遍历
//获取一个列表迭代器对象,该列表迭代器里面的指针默认指向0索引
//当中额外添加了一个方法:在遍历的过程中,可以添加元素->不能用add即集合添加元素的方法
//只能用迭代器自身拥有的添加元素的方法->用迭代器调用
ListIterator<String> it = list.listIterator();
while (it.hasNext()){
String s=it.next();
if("bbb".equals(s)){
//此时添加qqq
it.add("qqq");//不能用集合添加即list.add("qqq");
}
System.out.println(s);//循环中打印
}
/*运行结果为aaa
bbb
ccc*/
}
}
b.集合中遍历类(如自己创建的Student类):
方式1:不包装
package a25practice;
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
ArrayList<Student> list=new ArrayList<>();
Student s1=new Student(12,"zhangsan");
Student s2=new Student(13,"lisi");
list.add(s1);
list.add(s2);
Iterator<Student> it=list.iterator();
while (it.hasNext()){
Student s = it.next();//Student类
System.out.println(s);
/*运行结果为Student{age = 12, name = zhangsan}
Student{age = 13, name = lisi}*/
}
}
}
class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public String toString() {
return "Student{age = " + age + ", name = " + name + "}";
}
}
对于运行结果说明:
Student类里重写了顶级父类的toString方法
Student类里:public String toString() { return "Student{age = " + age + ", name = " + name + "}"; }
此时new一个Student对象会传重写后的toString里的内容:
如果不重写顶级父类的toString方法,new一个Student对象会传他的地址值:
方式2:包装
package a25practice;
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
ArrayList<Student> list=new ArrayList<>();
Student s1=new Student(12,"zhangsan");
Student s2=new Student(13,"lisi");
list.add(s1);
list.add(s2);
Iterator<Student> it=list.iterator();
while (it.hasNext()){
String s = String.valueOf(it.next());//实际为Student类,手动包装为String类
System.out.println(s);
/*运行结果为Student{age = 12, name = zhangsan}
Student{age = 13, name = lisi}*/
}
}
}
class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public String toString() {
return "Student{age = " + age + ", name = " + name + "}";
}
}
源码:
c.增强for遍历:
未用增强for之前:
//定义一个方法,用于对id进行唯一性判断
//需要所有人的id即要一个集合,弄出里面的id,还需要输入的新id;需要返回,若有相同的,返回true;若没有相同的,返回false
public static boolean contains(ArrayList<Person> list, String id) {
for (int i = 0; i < list.size(); i++) { //
//1.遍历得到集合中每一个学生
Person p = list.get(i);
//2.遍历得到集合中每一个学生id
String pId = p.getId();
//3.与输入的id进行比较
if (id.equals(pId)) {
//4.走if代表遇到了相同的,返回true
return true;
}
}
//5.循环完后还没结束方法,说明没有相同的
return false;
}
用增强for之后:
//定义一个方法,用于对id进行唯一性判断
//需要所有人的id即要一个集合,弄出里面的id,还需要输入的新id;需要返回,若有相同的,返回true;若没有相同的,返回false
public static boolean contains(ArrayList<Person> list, String id) {
for (Person p : list) { //此时直接得到学生对象
//1.遍历得到集合中每一个学生id
String pId = p.getId();
//2.与输入的id进行比较
if (id.equals(pId)) {
//3.走if代表遇到了相同的,返回true
return true;
}
}
//4.循环完后还没结束方法,说明没有相同的
return false;
}
d.抽象类也可以实现接口。
11.方法重写与重载的区别:
对于重写中,参数表相同是指参数类型必须一致,参数名可以不同
对于重载中,参数表不同指参数类型不同或者参数个数不同或者参数顺序不同
12.类的规则:
a.不建议把类设计为public型,因为可能破坏类的封装性,
类只能用友好修饰符和public修饰符修饰权限。
b.一个java文件中最多只能有一个公共类(public修饰的类)
如:
Test.java代表一个java文件,此时Student类和Test类只能**Test类是public类**
要想Student类能被public修饰,必须要在Student.java下申明
13.常见后缀:
在Java中,源代码文件的后缀通常是.java。当编写Java程序时,会创建一个以.java为后缀的源代码文件,其中包含了Java源代码。例如,一个简单的Java源代码文件可以命名为`myclass.java`,其中`myclass`是类的名称,而`.java`则是文件的后缀。
此外,经过编译之后的Java文件会生成以.class为后缀的文件,这是Java字节码文件。这些文件是Java虚拟机(JVM)可以理解和执行的。
在Java开发过程中,还会涉及到其他类型的文件,例如配置文件、资源文件等,它们通常会有不同的后缀,如.properties、.xml、.json等,但这些并不属于Java源代码文件或编译后的字节码文件。
请注意,文件的命名和后缀对于Java程序的正确运行和组织至关重要,因此需要遵循Java的命名规则和约定。
14.相加:
a.字符串和字符可以相加-->直接加
b.数字可以和字符相加-->此时字符用ASCII码参与计算
package NiuKePractice;
public class Test {
public static void main(String[] args) {
System.out.println("a"+'a');//运行结果为aa
System.out.println(1+'a');//运行结果为98
}
}
15.包装类如Integer(整数),Double(浮点数)转字符串:
如Integer: