Inner class. What is his purpose?

Can someone tell me what the goal is to have inner classes? I can think of a few, but maybe they are not good reasons for using inner classes. My reasoning is that the inner class is useful if you want to use a class that other classes cannot use. What else?

+5
java oop inner-classes
source share
5 answers

Inner classes can be used to simulate closures: http://en.wikipedia.org/wiki/Closure_(computer_science)#Java

+2
source share

When I was learning Java, we used inner classes for the GUI event handling classes. This is a kind of "one-time" class, which should not be accessible to other classes and applies only to the class in which it is located.

+3
source share

I use inner classes to define a structure that is best represented by the containing class, but it does not necessarily make sense to use a separate outer class to represent the structure.

To give an example, I have a class that represents a specific type of network device, and the class has certain types of tests that can be run on this device. For each test, there is also a potential set of errors that can be found. Errors can have different types of devices.

With this you can do things like

List<Error> errors = RemoteDeviceA.getErrors(); 

Using methods available from the inner class, for example

  for ( Error error : errors ) { System.out.println("MOnitor Type: " + error.getMonType()); ... } 

Of course, there are other ways to do this, this is just an internal class approach.

Simplified (aka incomplete) code for the above:

 public class RemoteDeviceA { private String host; private String user; private String password; private static List<Error> errors; public RemoteDeviceA(String user, String host, String password) { this.host = host; this.user = user; this.password = password; login(); } private void login() { // Logs in } public void runTestA() { List<Error> errorList = new ArrayList<Error>(); //loop through test results if (!value.equals("0")) { Error error = new Error(node, rackNum, shelfNum, slotNum, monType, value); if (error.isError()) { errorList.add(error); } } setErrors(errorList); } private static void setErrors(List<Error> errors) { RemoteDeviceA.errors = errors; } public List<Error> getErrors() { return errors; } public class Error { private String monType; private String node; private String rack; private String shelf; private String slot; private String value; private boolean error = false; private boolean historyError = false; private boolean critical = false; private boolean criticalHistory = false; Error(String node, String rack, String shelf, String slot, String monType, String value) { parseAlarm(node, rack, shelf, slot, monType, value); } private void parseAlarm(String node, String rack, String shelf, String slot, String monType, String value) { String modType = ""; if (monType.startsWith("ES_15") && !value.equals("0")) { setMonType("ES_15"); setError(true); } else if (monType.startsWith("SES_15") && !value.equals("0")) { setMonType("SES_15"); setError(true); } else if (monType.startsWith("BBE_15") && !value.equals("0")) { setMonType("BBE_15"); setError(true); } else if (monType.startsWith("UT_15") && !value.equals("0")) { setMonType("UT_15"); setError(true); setCritial(critical); } else if (monType.startsWith("ES_24") && !value.equals("0")) { setMonType("ES_24"); setHistoryError(true); setError(true); } else if (monType.startsWith("SES_24") && !value.equals("0")) { setMonType("SES_24"); setHistoryError(true); setError(true); } else if (monType.startsWith("BBE_24") && !value.equals("0")) { setMonType("BBE_24"); setHistoryError(true); setError(true); } else if (monType.startsWith("UT_24") && !value.equals("0")) { setMonType("UT_24"); setHistoryError(true); setError(true); setCriticalHistory(true); } else if (monType.startsWith("UT_15") && !value.equals("0")) { setMonType("UT_15"); setError(true); setCritial(true); } else if (monType.startsWith("LASPWR")) { float laserPwr = Float.valueOf(value); if (node.startsWith("LEM_EM")) { if ((laserPwr < 8.0) || (laserPwr > 12.0)) { setMonType("LASERPWR"); setError(true); } } else if (node.startsWith("LEM10")) { if ((laserPwr < 18.0) || (laserPwr > 22.0)) { setMonType("LASERPWR"); setError(true); } } } if (isError()) { setNode(node); setRack(rack); setShelf(shelf); setSlot(slot); setValue(value); setError(true); } } private void setMonType(String monType) { this.monType = monType; } public String getMonType() { return monType; } private void setNode(String node) { this.node = node; } public String getNode() { return node; } public void setRack(String rack) { this.rack = rack; } public String getRack() { return rack; } public void setShelf(String shelf) { this.shelf = shelf; } public String getShelf() { return shelf; } public void setSlot(String slot) { this.slot = slot; } public String getSlot() { return slot; } private void setValue(String value) { this.value = value; } public String getValue() { return value; } private void setError(boolean error) { this.error = error; } public boolean isError() { return error; } public void setCritial(boolean critical) { this.critical = critical; } public boolean isCritical() { return critical; } public void setCriticalHistory(boolean criticalHistory) { this.criticalHistory = criticalHistory; } public boolean isCriticalHistory() { return criticalHistory; } public void setHistoryError(boolean historyError) { this.historyError = historyError; } public boolean isHistoryError() { return historyError; } } } 
+2
source share

An implementation of a list that internally uses a linked list to hold items can make good use of the inner class to represent nodes in the list. I think you hit a nail on the head, saying that you will use a class where you want to use it inside the class but don’t want it to be open - the β€œone” class, which is really useful 'here'.

+1
source share

I use inner classes (in C ++) in situations where several classes not connected through inheritance have conceptually similar implementation details that form the implicit part of the open interface and should be named in the same way.

 class lib::Identifier { ... }; class lib::Person { public: class Identifier : public lib::Identifier { ... }; }; class lib::File { public: class Identifier : public lib::Identifier { ... }; }; 

This makes it convenient to use Identifier , Person::Identifier and File::Identifier as simply Identifier in their respective fields.

+1
source share

All Articles