什么时候使用static关键字? 它有什么作用? 没关系,IDE告诉我在哪里添加它!
有了这种态度,我的主班级看起来像这样:
例子1
public class Main { static Contact contact = new Contact(); static Input input = new Input();public static void 主要(String[] args) { showMenu();}public static void showMenu() {
int menuChoice;
menuChoice = input.menuChoice();
switch (menuChoice) {
case 1: updateContact();
default: break;
}
}
static void updateContact() {
updateContactFields();
showContact();
}
static void updateContactFields() {
// lots of update calls
}
static void showContact() {
// Lots of prints
showMenu();
}
}
出于很多原因,这是一次火车事故,但是静态的一切都在引起我不知道的问题。
朱尔斯的坏举
我有优先级,然后找出所有这些通用关键字(不是这样)的含义很低。 无论如何,该程序都能正常工作,并且如果我创建了一个新方法,IntelliJ告诉我无法从静态上下文引用非静态方法,因此所有方法都变为静态。
可是,在我的脑后,有些事困扰着我。
- Java类中的main方法必须是静态的
- 我使用的每种方法都是通过main方法直接或间接调用的
- 其他类调用的方法不必是静态的,但也可以 是
那么,为什么要一直添加呢?
封锁者
最终,使用循环更好的递归和使整个类静态化的组合导致状态无法调试的问题。 熟悉Java的人快速浏览了一下,问我是否知道static做了什么。
他们用Ruby术语将其描述为使某类成为类方法或变量。 我最多只需要实例,但是无意间使所有事情都全球化了。
解决方案/示例2
public class Main {
Input input = new Input();
ArrayList<Contact> contactList = new ArrayList<>();
public static void main(String[] args) {
Main main = new Main();
main.showMenu();
}
public void showMenu() {
boolean complete = false;
while (!complete) {
printMenuOptions();
int userInput = input.menuChoice();
switch (userInput) {
case 1: {
newContact();
break;
}
case 2: {
updateExistingContact();
break;
}
case 3: {
showContact();
break;
}
default:
complete = true;
break;
}
}
}
void printMenuOptions() {
// logs
}
void newContact() {
contactList.add(new Contact(input.confirmInput("first 名称"), input.confirmInput("last name"), input.confirmInput("address"), input.confirmInput("phone number"), input.confirmInput("DOB in dd/mm/yyyy format"), input.confirmInput("email")));
}
void updateExistingContact() {
if (checkForContacts()) {
displayContacts();
try {
updateContactFields(contactList.get(Integer.parseInt(input.confirmInput("contact choice")) - 1));
} catch (Exception e) {
System.out.println("No such contact");
}
}
}
boolean checkForContacts() {
if (contactList.size() == 0) {
System.out.println("There are no contacts yet");
return false;
} else {
return true;
}
}
void updateContactFields(Contact contact) {
// logs and update calls
}
void showContact() {
if (checkForContacts()) {
displayContacts();
Contact contact = null;
try {
contact = contactList.get(input.contactChoice() - 1);
} catch (Exception e) {
System.out.println("No such contact");
showMenu();
}
printContactDetails(contact);
}
}
void printContactDetails(Contact contact) {
// lots of logs
}
void displayContacts() {
System.out.println("Please select a contact");
for (int i = 0; i < contactList.size(); i++) {
System.out.println(i + 1);
}
}
}
(注意:这里也有其他功能)
为了避免从静态方法中调用方法main
, 你刚才:
- 在main方法中创建Main类的实例
- 从Main实例调用任何方法(例如main.displayContacts())
- 现在,您只需要在最佳实践中将事情静态化即可
什么时候应该是静态的?
我很高兴您问:假设我有一个联系人列表,并且每个联系人都有几个属性。 如果它们共享一个公共属性,则该变量可以是静态的以节省内存。
class Contact {
String name;
static String 国家 = "Arstotzka";
int age;
// and so on
}
如果我有10个Contact实例,name
变量将被分配10次内存。 另一方面,国家
是静态的,因此只分配一次内存,但是有很多实例。 它不必是静态的,但从内存角度来说,这样做是更有效的。
笔记:
- 它仍然可以更改,但是与非静态变量相比,更改的可能性较小。
- 静态变量还必须使用值初始化,因为您说的是变量及其值是类固有的。
类方法
使用类方法而不实例化类,如示例1中的情况。Main从未实例化,因此,如果我调用任何方法,则它们必须是类级别而不是对象级别。
例子3
class Contact {
String name;
static String country = "Arstotzka";
int age;
// and so on
static void updateCountry() {
country = "Republia";
}
}
示例3中的static方法更新了static变量country
,因此每个Contact实例现在将具有字符串值'Republia'而不是'Arstotzka'。
概括
- 静态变量是类级别的变量,因此被实例继承,并且必须在创建实例之前进行初始化
- 静态方法是类方法,在不实例化类的情况下调用静态方法
- 如果要使用实例方法,则需要实例化您的类(现在已在实例变量/方法与类实例之间建立了联系)
这远非详尽无遗,但是如果我早些时候进行研究,那将为我节省很多时间和痛苦。
让我知道您的想法,无论您认为这是清楚而有用的,还是我错过了一些大事并做出了一些错误的断言!