方法的内存

一、方法调用的基本内存原理:

Java内存分配

  1. 栈: 方法运行时使用的内存方法进栈运行,运行完毕就出栈

  2. 堆: newl出来的,都在堆内存中开辟了一个小空间

  3. 方法区: 存储可以运行的class文件

  4. 本地方法栈:JVM在使用操作系统功能的时候使用和我们开发无关

  5. 寄存器:给CPU使用和我们开发无关

方法被调用后就会进栈执行

方法内所有代码执行完毕之后,方法就会出栈,方法出栈之后变量就不会再存在了
package com.itheima.Method;
//方法调用的基本内存原理
public class Demo11Test05 {
public static void eat() {
study();
System.out.println("吃饭");
sleep();
} public static void sleep() {
System.out.println("睡觉");
} public static void study() {
System.out.println("学习");
} public static void main(String[] args) {
eat();
}
}

运行结果:

学习

吃饭

睡觉

运行原理:

计算机先进栈,进入main方法;main方法调用了eat方法,此时eat方法进栈;eat方法又调用了study方法,study方法进栈,执行study方法代码,打印学习;学习语句打印完毕后,study方法内的代码全部执行完毕,study方法进行出栈,然后会到study方法调用处继续执行sout“吃饭”,打印吃饭;打印完后又调用了sleep方法,打印睡觉,打印完毕后sleep方法内的代码全部执行完毕,sleep方法出栈,回到调用处继续往下执行;最后eat方法代码执行完毕,main方法内的代码执行完毕,main方法进行出栈。

二、方法传递基本数据类型的内存原理:

  1. 基本数据类型和引用数据类型:

基本数据类型:整数类型、浮点类型、布尔类型、字符类型

引用数据类型:处理上面的其他所有类型

基本数据类型:

在基本数据类型中存储的是真实的数据,数据值是存储在自己的空间中

特点:赋值给其他变量,也是赋的真实的值

引用数据类型:
只要是new出来的就都是引用数据类型

变量中存储的是地址值
引用数据类型:数据值是存储在其他空间中,自己空间中存储的是地址值
特点:赋值给其他变量赋的地址值

三、方法传递引用数据类型的内存原理:

eg1:

package com.itheima.Method;
//方法传递引用数据类型的内存原理
public class Demo11Test06 {
public static void change(int number) {
number = 200;
} public static void main(String[] args) {
int number = 100;
System.out.println("调用change方法前:"+number);//100
change(number);
System.out.println("调用change方法后:"+number);//100
}
}

运行结果:

100

100

原因:

当主函数调用change(number)的时候,change(number)里面的number已经是两百了,但他等到他回到调用处的时候,change(number)已经出栈了。此时调用change方法后的number只有main方法里面的number=100

当我们要打印出200时可以这样编写代码:

package com.itheima.Method;

public class Demo11Test07 {
public static int change(int number) {
number = 200;
return number;
} public static void main(String[] args) {
int number = 100;
System.out.println("调用change方法前:"+number);//100
number = change(number);
System.out.println("调用change方法后:"+number);//200
}
}

运行结果:

100

200

eg2:

package com.itheima.Method;
//方法传递引用数据类型的内存原理
public class Demo11Test08 {
public static void change(int[] arr){
arr[1]= 600;
} public static void main(String[] args) {
int[] arr = {10,20,30};
System.out.println("调用change方法前:"+arr[1]);
change(arr);
System.out.println("调用change方法后:"+arr[1]);
}
}

运行结果:

20

600

运行原理:

因为new了一个新数组,所以有两个空间,一个栈内存,一个堆内存。程序刚运行的时候,main方法先进栈,定义了一个变量数组arr,堆里面开辟了一个空间存储arr这个数组里面的索引然后堆里面空间有一个地址值,用来存储arr这个数据的地址。等号把右边的地址值赋值给arr,arr可以通过地然后执行main方法里面的第二行代码,获取到arr索引为1的数据,打印arr[1]。然后调用change方法,Change方法进栈,调用的用的把arr的值传递给了change,现在Change里面的arr记录的是arr的地址值,相当于把地址值交给了change里面的行参。此时main方法里面的arr和change方法里面的arr指向的是同一个地址;然后执行change方法里面的代码arr[1]=600, 把600赋值给地址值的1索引,此时地址值里面的1索引发生改变;然后change方法执行完毕,change方法进行出栈;回到方法调用处继续执行打印arr[1];因为打印的地址是修改后的结果,所以arr[1]=600

结论:传递引用数据类型时递的是地址值,行参的改变,影响实际参数的值。

方法的练习

练习1:

package com.itheima.Method;

import java.sql.SQLOutput;
import java.util.Scanner; /*卖飞机票
需求:机票价格按照淡季,旺季头等舱和经济舱收费,输入机票原价。月份和头等舱或经济舱
按照如下规则计算机票价格:旺季(5~10月)头等舱9折,经济舱8.5折。淡季(11月~来年四月)头等舱7折,经济舱6.5折
*/
public class DemoPractice01 {
public static void main(String[] args) {
Scanner price = new Scanner(System.in);
System.out.println("请输入机票原价:");
double primaryPrice = price.nextInt();
Scanner m = new Scanner(System.in);
System.out.println("请输入月份");
int month = m.nextInt();
Scanner g = new Scanner(System.in);
System.out.println("请输入您的舱数等级(1:头等舱,2:经济舱):");
int seat = g.nextInt();
double countPrice = 0;
double lastPrice = 0;
if (month >= 5 && month <= 10) {
if (seat == 1) {
lastPrice = primaryPrice * 0.9;
} else if (seat == 2) {
lastPrice = primaryPrice * 0.65;
} else {
System.out.println("没有这个座位");
}
} else if ((month >= 1 && month <= 4) || (month >= 11 || month <= 12)) {
if (seat == 1) {
lastPrice = primaryPrice * 0.85;
} else if (seat == 2) {
lastPrice = primaryPrice * 0.7;
} else {
System.out.println("没有这个座位");
}
} else {
System.out.println("您输入的月份不合法");
}
System.out.println(lastPrice);
}
}

运行结果:

请输入机票原价:

1000

请输入月份

6

请输入您的舱数等级(1:头等舱,2:经济舱):

1

900.0

练习1改进:(用方法改进)

package com.itheima.Method;

import java.util.Scanner;
//改进!!!
/*卖飞机票
需求:机票价格按照淡季,旺季头等舱和经济舱收费,输入机票原价。月份和头等舱或经济舱
按照如下规则计算机票价格:旺季(5~10月)头等舱9折,经济舱8.5折。淡季(11月~来年四月)头等舱7折,经济舱6.5折
*/
public class DemoPractice02 {
public static double getPrice(double ticket,int seat,double v1,double v2) { if (seat == 1) {
ticket = ticket * v1;
} else if (seat == 2) {
ticket = ticket * v2;
} else {
System.out.println("没有这个舱位");
}
return ticket;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入机票原价:");
double ticket = sc.nextInt();
System.out.println("请输入月份");
int month = sc.nextInt();
System.out.println("请输入您的舱数等级(1:头等舱,2:经济舱):");
int seat = sc.nextInt();
double lastPrice = 0;
if (month >= 5 && month <= 10) {
//旺季
ticket = getPrice(ticket,seat,0.9,0.85);
} else if ((month >= 1 && month <= 4) || (month >= 11 || month <= 12)) {
//淡季
ticket = getPrice(ticket,seat,0.7,0.65);
} else {
System.out.println("您输入的月份不合法");
}
System.out.println(ticket);
}
}

运行结果:

请输入机票原价:

1000

请输入月份

6

请输入您的舱数等级(1:头等舱,2:经济舱):

1

900.0

练习1改进:(用快捷键自动生成方法:)

package com.itheima.Method;

import java.util.Scanner;

//用系统快捷键Ctrl+alt+m自动抽取方法,提取想要写成方法的代码,然后系统会自动生成一个方法
/*卖飞机票
需求:机票价格按照淡季,旺季头等舱和经济舱收费,输入机票原价。月份和头等舱或经济舱
按照如下规则计算机票价格:旺季(5~10月)头等舱9折,经济舱8.5折。淡季(11月~来年四月)头等舱7折,经济舱6.5折
*/
public class DemoPractice03 {
public static void main(String[] args) {
Scanner price = new Scanner(System.in);
System.out.println("请输入机票原价:");
double primaryPrice = price.nextInt();
Scanner m = new Scanner(System.in);
System.out.println("请输入月份");
int month = m.nextInt();
Scanner g = new Scanner(System.in);
System.out.println("请输入您的舱数等级(1:头等舱,2:经济舱):");
int seat = g.nextInt();
double countPrice = 0;
double lastPrice = 0;
if (month >= 5 && month <= 10) {
lastPrice = getPrice(seat, lastPrice, primaryPrice, 0.9, 0.65);
} else if ((month >= 1 && month <= 4) || (month >= 11 || month <= 12)) {
lastPrice = getPrice(seat, lastPrice, primaryPrice, 0.85, 0.7);
} else {
System.out.println("您输入的月份不合法");
}
System.out.println(lastPrice);
} private static double getPrice(int seat, double lastPrice, double primaryPrice, double x, double x1) {
if (seat == 1) {
lastPrice = primaryPrice * x;
} else if (seat == 2) {
lastPrice = primaryPrice * x1;
} else {
System.out.println("没有这个座位");
}
return lastPrice;
}
}

运行结果:

请输入机票原价:

1000

请输入月份

6

请输入您的舱数等级(1:头等舱,2:经济舱):

2

650.0

练习总结:

练习1:找质数

package com.itheima.Method;
//找质数:判断101~200之间有多少个质数,并输出所有质数
public class DemoPractice04 {
public static void main(String[] args) {
int count = 0;
for (int i = 101; i < 200; i++) {
boolean flag = true;
for (int j = 2;j< i;j++){
if(i%j==0){
flag = false;
break;
}
}
if (flag){
System.out.println(i+"是一个质数");
count++;
}
}
System.out.println("一共有"+count+"个质数");
}
}

运行结果:

101是一个质数

103是一个质数

107是一个质数

109是一个质数

113是一个质数

127是一个质数

131是一个质数

137是一个质数

139是一个质数

149是一个质数

151是一个质数

157是一个质数

163是一个质数

167是一个质数

173是一个质数

179是一个质数

181是一个质数

191是一个质数

193是一个质数

197是一个质数

199是一个质数

一共有21个质数

练习2:数组元素的复制

package com.itheima.Method;
/*数组元素的复制
需求:把一个数组中的元素复制到另一个新数组中
*/
public class 数组元素的复制练习02 {
public static void main(String[] args) {
int[] arr = {45,21,37,69,54,66,73};
int[] newArr = new int[arr.length];
for(int i=0;i<arr.length;i++){
newArr[i] = arr[i];
}
for (int i = 0; i < newArr.length; i++) {
System.out.print(newArr[i]+" ");
}
}
}

运行结果:

45 21 37 69 54 66 73

练习3:评委打分

package com.itheima.Method;

import java.util.Scanner;

/*评委打分:
需求:在唱歌比赛中有六名评委给选手打分,分数范围是0~100之间的整数,选手的最后得分为
去掉最高分,去掉最低分后的四个评委的平均分
*/
public class 评委打分练习03 {
public static int[] getScore() {
int[] scores = new int[6];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; ) {
System.out.println("请分别输入六个分数");
int score = sc.nextInt();
if (score>=0&&score<=100){
scores[i] = score;
i++;//只有输入一个合法的数据,系统才会存入,否则不会存入
}else {
System.out.println("成绩超出范围,继续录入,当前i为:"+i);
}
}
return scores;
} public static void main(String[] args) {
int[] scoreArr = getScore();
double max = scoreArr[0];
double min = scoreArr[0];
double lastScore = 0;
int sum = 0;
for (int i = 0; i < scoreArr.length; i++) {
System.out.println(scoreArr[i]);
if (max>scoreArr[i]){
max = scoreArr[i];
}
if (min<scoreArr[i]){
min = scoreArr[i];
}
sum +=scoreArr[i];
}
lastScore = (sum-max-min)/(scoreArr.length-2);
System.out.println("去掉一个最高分一个最低分,最后分数为"+lastScore);
}
}

运行结果:

请分别输入六个分数

10

请分别输入六个分数

20

请分别输入六个分数

30

请分别输入六个分数

40

请分别输入六个分数

50

请分别输入六个分数

60

10

20

30

40

50

60

去掉一个最高分一个最低分,最后分数为35.0

练习4:数字加密

package com.itheima.Method;

import java.util.Scanner;

/*
数字加密:
某系统的数字密码(大于0),比如1983,采用加密方式进行传输。
规则如下:每位数加上5,再对十求余,最后将所有数字反转,得到一串新数
*/
public class 数字加密练习04 {
public static void main(String[] args) {
int[] arr ={1,9,8,3};
for (int i = 0; i < arr.length; i++) {
arr[i] += 5;
}
for (int i = 0; i < arr.length; i++) {
arr[i] %=10;
}
for (int i = 0,j =arr.length-1; i < j; i++,j--) {
int tem = arr[i];
arr[i] = arr[j];
arr[j] = tem;
}
int number = 0;
for (int i = 0; i < arr.length; i++) {
number =number*10+arr[i];
}
System.out.println("加密后的密码是:"+number);
}
}

运行结果:

加密后的密码是:8346

练习5:数字解密

package com.itheima.Method;
/*
数字解密:
每位数加上5,再对10求余,得到一串新数,按照以上规则进行解密
*/
public class 数字解密练习05 {
public static void main(String[] args) {
int[] arr = {8,3,4,6};
//反转
for (int i = 0,j=arr.length-1; i < j; i++,j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//由于加密是通过对10取余的方式进行获取。
//所以在解密的时候就需要判断0~9之间加10,5~9之间数字不变。
for (int i = 0; i < arr.length; i++) {
if (arr[i]>=0&&arr[i]<=4){
arr[i] = arr[i]+10;
}
}
//每一位减5
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i]-5;
}
int number = 0;
for (int i = 0; i < arr.length; i++) {
number = number*10+arr[i];
}
System.out.println(number);
}
}

运行结果:

1983

练习6:抢红包游戏

package com.itheima.Method;

import java.util.Random;

/*
抢红包游戏 :
需求 :一个大V直播抽奖奖品是现金红包分别有 2,588 ,888, 1000,10000个奖金
请使用代码模拟抽奖打印出每个奖项奖项的出现顺序要随机且不重复。
*/
public class 抢红包练习06 {
public static boolean contains(int[] arr, int prize) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == prize) {
return true;
}
}
return false;
} public static void main(String[] args) {
int[] arr = {2,588,888,1000,10000};//1、定义数组表示奖池
int[] newArr = new int[arr.length];//2、定义新数组用于存储抽奖结果
//3、抽奖
Random r = new Random();//定义一个随机变量
//因为有五个奖项,所以要循环五次
for (int i = 0; i < 5; i++) {
int randomIndex = r.nextInt(arr.length);//获取随机索引
int prize = arr[randomIndex];
//判断当前奖项是否存在,如果存在则重新抽取,如果不存在就表示有效奖项
boolean flag = contains(newArr, prize);
if (!flag) {
newArr[i] = prize;//把当前抽取道德奖项添加到newArray中
//添加完毕之后,移动索引
i++;
}
}
//4、遍历newArr
for (int i = 0; i < newArr.length; i++) {
System.out.println(newArr[i]);
}
}
}

练习6改进:抢红包游戏

package com.itheima.Method;

import java.util.Random;

/*
抢红包游戏 改进:
需求 :一个大V直播抽奖奖品是现金红包分别有 2,588 ,888, 1000,10000个奖金
请使用代码模拟抽奖打印出每个奖项奖项的出现顺序要随机且不重复。
*/
public class 抢红包练习07 {
public static void main(String[] args) {
//1、把奖池里面的所有奖项打乱顺序
int[] arr = {2,588 ,888, 1000,10000};
Random r = new Random();
for (int i = 0; i < arr.length; i++) {
int randomIndex = r.nextInt(arr.length);//获取随机索引
int temp = arr[i];
arr[i] = arr[randomIndex];
arr[randomIndex] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}

运行结果:

1000

2

588

888

10000

java方法的内存及练习的更多相关文章

  1. Java运行时内存划分

    这篇文章可以说是摘抄自周志明的<深入理解Java虚拟机>,但是加上了自己的理解,印象可以更深些. Java虚拟机在执行Java程序的时候会把他所管理的内存划分为若干个不同的数据区域,各个区 ...

  2. Android进程so注入Hook java方法

    本文博客链接:http://blog.csdn.net/qq1084283172/article/details/53769331 Andorid的Hook方式比较多,现在来学习下,基于Android ...

  3. 关于JAVA中的static方法、并发问题以及JAVA运行时内存模型

    一.前言 最近在工作上用到了一个静态方法,跟同事交流的时候,被一个问题给问倒了,只怪基础不扎实... 问题大致是这样的,“在多线程环境下,静态方法中的局部变量会不会被其它线程给污染掉?”: 我当时的想 ...

  4. java优化占用内存的方法(一)

    java做的系统给人的印象是什么?占 内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点.其实从理论上来讲java做的系统并不比其他语言开发出来的 系统更占用内存, ...

  5. java执行程序的内存分析系列专栏二之static变量和方法内存分析

    昨天写了简单的聊了下java执行程序时简单的内存划分,今天我们接着往下聊,聊聊static变量和方法的内存分析. 1.static变量和方法的第一个特性内存分析 statiic变量和方法的第一个特性能 ...

  6. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

  7. Java进程占用内存过高,排查解决方法

    最近收到邮件报警,说内存使作率达到84%.如下图: 解决方法: A:可能是代码原因导致的问题: 1.使用命令:top 查看当前进程的状态 2.从上图可以看到PID:916的java进程占用内存较大.定 ...

  8. Java中类,对象,方法的内存分配

    Java中类,对象,方法的内存分配 以下针对引用数据类型: 在内存中,类是静态的概念,它存在于内存中的CodeSegment中. 当我们使用new关键字生成对象时,JVM根据类的代码,去堆内存中开辟一 ...

  9. Java 字符串常量存放在堆内存还是JAVA方法区?

    JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池. JDK1.8开始,取消了Java方法区,取而代之的是位于直接内 ...

  10. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

随机推荐

  1. Linux 环境下使用 sqlplus 访问远程 Oracle 数据库

    自己最近需要在 Oracle 生产环境检查一些数据,但是目前大多数的生产环境,出于安全考虑,不会提供图形界面让你使用类似 Navicat 工具让你直接访问数据库,网上找了很多资料,大部分都比较过时或者 ...

  2. SP277 CTGAME - City Game 题解

    题目传送门 前置知识 单调栈 解法 令 \(f_{i,j}(1 \le i \le n,1 \le j \le m)\) 表示从 \((1,j)\) 到 \((i,j)\) 中以 \((i,j)\) ...

  3. NC22593 签到题

    题目链接 题目 题目描述 恭喜你找到了本场比赛的签到题! 为了让大家都有抽奖的机会,只需要复制粘贴以下代码(并且稍微填下空)即可 AC: (我超良心的) #include <algorithm& ...

  4. P3078题解

    P3078题解 看到题解区,我有点震惊,什么贪心.线段树.各种优化都有,在此%%%.但其实这道题一个小小的差分就可解决. 前置芝士:前缀和/差分 by OI Wiki 题意简述 在一个 $card$ ...

  5. java 从零开始手写 redis(九)LRU 缓存淘汰算法如何避免缓存污染

    前言 java从零手写实现redis(一)如何实现固定大小的缓存? java从零手写实现redis(三)redis expire 过期原理 java从零手写实现redis(三)内存数据如何重启不丢失? ...

  6. Zabbix 配置笔记

    Zabbix Server 安装参考 https://www.cnblogs.com/clsn/p/7885990.html 安装脚本 #!/bin/bash #clsn #设置解析 注意:网络条件较 ...

  7. 3分钟总览微软TPL并行编程库

    有小伙伴问我每天忽悠的TPL是什么?☹️ 这次站位高一点,严肃讲一讲. 引言 俗话说,不想开飞机的程序员不是一名好爸爸:作为微软技术栈的老鸟,一直将代码整洁之道奉为经典, 优秀的程序员将优雅.高性能的 ...

  8. linux和unix中的IO模型总结

    高性能网络IO编程模型 一.I/O模型简介 在一个 linux 操作系统中,一般分为用户空间和内核空间. 用户空间一般就是我们进行应用程序编程的地方. 内核空间就是 linux 操作系统自己运行的一些 ...

  9. [BUUCTF][Web][极客大挑战 2019]EasySQL 1

    打开靶机对应的url 界面显示需要输入账号和密码 分别在两个输入框尝试加单引号尝试是否有sql注入的可能,比如 123' 发现两个框可以注入,因为报了个错误信息 You have an error i ...

  10. 网络通信部分之bs/cs架构,网络概念,osi七层网络模型,TCP/UDP协议---day27

    1.网络开发的两大架构c/s,b/s # ### 1.网络开发的两大架构 a文件 -> b文件 借助c文件 a文件和b文件进行数据交流,借助c文件中转数据 a文件把数据放在c文件中,b文件从c文 ...