练习题(重点)
自己的话介绍java:
首先是高级语言的面向对象
语言
体系结构(javase、javaee、javame)
好处、特性优势(记得那些术语(跨平台/可移植性、安全性、简单性、健壮性、面向对象、高性能、分布式、多线程))
(夸克,安检,见面,高分 ,多)
要提出核心:垃圾回收和跨平台
了解:java是面向对象和面向过程结合的,宏观整体上是面向对象的,具体实现是面向过程的
java流行的原因:
好处、特性优势(记得那些术语(跨平台/可移植性、安全性、简单性、健壮性、面向对象、高性能、分布式、多线程))
(夸克,安检,见面,高分 ,多)
要提出核心:垃圾回收和跨平台
java跨平台原理:
借助虚拟机进行的跨平台,对上(字节码文件)是统一接口,对下(根据操作系统生成对应的机械码)是不同的输出
执行java命令后,背后对应的虚拟机操作是什么?
1.启动jvm虚拟机
2.调用类加载器 classloder ----去寻找字Demo1节码文件
3.调用jvm虚拟机里的解释器,逐行将字节码解释成 010101 的可执行文件。
文档注释和多行注释的区别是什么?
文档注释是/** */ 有很多模板变量 会生成独立的api文件,达到了注释脱离代码的效果
多行注释是/* */
java变量类型结构图
解释代码str1==str2为什么一个true一个false
双等号比引用变量时是比地址
因为字面变量是常量池里,特性:相同的变量信息只保存一个。
new创建的是在堆里开辟的两个空间。
(引用类型赋值是将地址赋值过去,比如str1 = str2;再进行==的判断就是true)
上机题:
package com.jr.subject;
import java.util.Scanner;
public class Test01 {
public static void main(String[] args) {
System.out.println("****欢迎使用线上商城平台****");
System.out.println("商品展示如下:");
System.out.println("序号\t商品名称\t商品价格");
System.out.println("1\t\t羽绒服\t375");
System.out.println("2\t\t棉鞋\t263");
System.out.println("3\t\t棉袜\t9.5");
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要购买的商品(输入0退出程序)");
int num = sc.nextInt();
double money = 0;//商品价格
int num2 = 0;//购买数量
double sum = 0;//总消费
double timeSum = 0;//当前消费
while (num != 0){
switch (num){
case 1:
money = 375;break;
case 2:
money = 263;break;
case 3:
money = 9.5;break;
default:
System.out.println("输入有误");
System.out.println("一共消费:"+sum+"元\n感谢使用!程序退出");
System.exit(0);
}
System.out.println("请输入你要购买的数量");
num2 = sc.nextInt();
timeSum = num2 * money;
sum += timeSum;
System.out.println("本次消费:"+timeSum+"元");
System.out.println("请输入你要购买的商品(输入0退出程序)");
num = sc.nextInt();
}
System.out.println("一共消费:"+sum+"元");
System.out.println("感谢使用!程序退出!");
}
}
方法(理解)
背下面干货分享
public class Demo1 {
public static void main(String[] args) {
System.out.println("和是"+Demo1.getSum(50,100));//类下的静态要通过类名.方法()
System.out.println("和是"+getSum(50,100));//由于是本类下所以可以省
}
public static int getSum(int start,int end){//指定范围内,所有偶数的和
int sum = 0;
for (int i = start; i <= end; i++) {
if (i % 2 == 0){
sum += i;
}
}
return sum;
}
public static int getSum(double start,int end){//重载
return 1;
}
public static int getSum(int start){//重载
return 1;
}
/*
面向过程:(一趟线全整完)关注的是细节的实现
面向对象:(一人负责一个部分(过程),对应的事找对应的人)
《面向对象解题思路》
1.筛选符合条件的类
2.通过类 来创建对象
3.对象.方法() --问题就可以解决
【方法】
1.什么是方法?作用是什么?
方法是在类中定义的,归对象所拥有(静态方法除外)
1)方法是用于解决一类问题的,一定是通用的。
2)有了方法存在,相同的代码不用重复写二遍
3)更利于项目的合作开发,便于项目的修改、扩展。
2.如何使用方法:
第一步:定义方法 公式中[]表示可以省略
公式:[权限修饰符][方法修饰符][返回值类型]方法名([参数列表])[{
方法体;[return;]
}]
1)权限修饰符:public、protected、省略不写(默认的)、private
public --公有的,使用范围:本项目所有类。
private --私有的,使用范围:本类下。
protected --受保护的 1.继承模块学。
默认的 --默认的,本包里的所有类。
2)方法修饰符:static、final、protected
static --静态的,1.提前加载(项目运行前就已经加载到内存)2.该方法归当前整个类所拥有。
final --最终的,1.变量(变量名全大写)变成常量2.方法不能被重写3.类不能被继承。
abstract --抽象的,1.方法没有方法体2.抽象类(有构造器)中不一定有抽象方法,有抽象方法的类一定是抽象类。
synchronization --同步的(),1.解决多线程(单线程一条线执行,多线程是多个线可同时执行(并行会抢资源))数据不安全问题,
native --本地的,意味着没有方法体 原因是 方法体的实现是其他编程语言完成的,不需要java进行编译,可以直接运行
3)返回值类型(回应给调用该方法的位置需要的类型):void、所有数据类型
无返回值类型 ###构造方法没有返回值类型###
有返回值类型 java中所有的类型 一般来说程序的中间环节一定是有返回值类型
空返回值类型 void 没有信息需要返回给下个环节
4)方法名/标识符:
命名规范和规则同变量名(小驼峰)
5)参数列表:(参数类型1 形参名1,参数类型2 形参名2)
方法体中出现的一些不确定因素(实参传给形参)就是参数
6)方法体
具体的 通用的 解决问题的实现步骤
7)return(有返回值类型必须有)
结束访前方法,一般出现在方法的最后一行
第二步:调用/使用方法
类名 对象名=new 类名();
对象名.方法();
1)静态方法: 类名.方法();
2)非静态方法: 对象名.方法();
3)本类下的方法:静态调用静态,非静态调用非静态 方法名()直接调用;
3.方法的重载:
定义:同一个类下,方法名相同,参数列表不同(类型、个数、顺序有一个不同就可以)
与返回值和访问修饰符无关的两个或两个以上的方法,就叫方法间的互为重载
条件:同一个类下
方法名必须相同
参数列表必须不同
重载的目的:1.一个方法解决一类问题,相似功能可以设置相同方法名。
(好处:在方法调用的时候,由原来程序员搜索查找改为程序本身自动查找)
2.方法命名时,相似功能可以使用相同名字。
*/
}
其他(了解)
有面向对象就不需要面向过程了(×) 面向对象的细节是面向过程实现的
public static void main(String[] args) {
Integer a =new Integer(100);
test(a);//Integer是引用类型,所以也是值传递
System.out.println(a);//和String一样有不可变性(在源码中,int值是final修饰的,一旦赋值就不能改变)
}
public static void test(Integer a){
a = 200;
}
其他(重点)
无返回值类型:构造方法没有返回值类型
有返回值类型:java中所有的类型 一般来说程序的中间环节一定是有返回值类型
空返回值类型:void
方法的重载(重点)
方法的重载:同一个类下,方法名相同,参数列表不同(类型、个数、顺序有一个不同就可以)
与返回值类型和修饰符无关
方法的实参传递给形参的时候一定要注意:一切都是值传递
:
方法的传参(自己理解,偏重点)
引用数据类型传参:(准确的来说是拷贝了一个引用变量指向那个值)
在Java中,参数传递是按值传递的,这意味着在方法调用时,传递给方法的是实际参数的拷贝。对于基本数据类型,这是原始值的拷贝,而对于对象,这是对象引用的拷贝。
下面是自己找的,方便理解
public void test() {//基本数据类型值传递
int a = 1;
change(a);
System.out.println("a的值:" + a);
}
private void change(int a) {
a = a + 1;
}
// 输出a的值:1(没变)
public void test() {//引用数据类型,赋值地址给新变量
User user = new User();
user.setAge(18);
change(user);
System.out.println("年龄:" + user.getAge());
}
private void change(User user) {
user.setAge(19);//赋值了份对象,每次都是改值,如下图
}
// 输出年龄:19(变了)
public void test() {
User user = new User();
user.setAge(18);
change(user);
System.out.println("年龄:" + user.getAge());
}
private void change(User user) {
user = new User();//因为new了所以开辟新空间来设置age为19
user.setAge(19);
}
// 输出年龄:18(没变)
说到这里,大家差不多懂了,但是回头看最开始的那个问题,传入String类型的变量,String是引用类型,按道理,原变量是会被改变的呀,结果怎么是不变呢?
public void test() {
String str = "hello";
change(str);
System.out.println(str);
}
private void change(String str) {//String的值是不可变性,修改String的值其实是new了个对象
str = "world";
}
//输出结果:hello
String变量比较特殊,我们看String的源码可以知道,String的值是通过内部的char[]数组来维护的,但是这个数据定义的是final类型的,因此,String的值是不可变的(不可变性)
。我们平时修改String的值,其实是重新new了一个String对象。
重点例题(14节的题):
public class TestStringBuffer {
public static void main(String args[]) {
StringBuffer a = new StringBuffer("A");
StringBuffer b = new StringBuffer("B");
mb_operate(a, b);
System.out.println(a + "." + b);
}
static void mb_operate(StringBuffer x, StringBuffer y) {
x.append(y);
y = x;
}
}
解答:在Java中,参数传递是按值传递的,这意味着在方法调用时,传递给方法的是实际参数的拷贝。对于基本数据类型,这是原始值的拷贝,而对于对象,这是对象引用的拷贝。
在这个方法中,x.append(y) 修改了 x 对象,将 y 的内容追加到了 x 后面。但是 y = x 这一行只是将局部变量 y 的引用指向了 x,并没有影响到原始的 b 对象
。因为这只是修改了局部变量 y 的引用,不会改变原始的 b 对象。
自己整理: | ||
---|---|---|
首先 | a->“A” | b->“B” |
调用mb_operate(a, b)后: | a->“A”,x->“A” | b->“B”,y->“B” |
执行x.append(y)后:改变的是值 | a->“AB”,x->“AB” | b->“B”,y->“B” |
执行y = x;后:改变的是y指向的地址 | a->“AB”,y->x->“AB” | b->“B” |