Where the data of the class' objects will be stored? - java

I'm having a Class and array of that class' objects and each object has its own values. Now I want to access all the details of that class from another class. Please help me solve this. I've to display the details of FirstClass' objects (say f[0] & f[1]) in SecondClass.
public class FirstClass{
int first,second,total;
public FirstClass(int first,int second) {
this.first=first;
this.second=second;
this.total=first+second;
}
}
public class SecondClass {
public void display() {
//Display all the details of FirstClass
}
}
public class MainClass {
public static void main(String args[]) {
FirstClass f[]=new FirstClass[2];
f[0]=new FirstClass(2,4);
f[1]=new FirstClass(6,4);
SecondClass sec = new SecondClass();
sec.display();
}
}

One way: by simply changing your display() method to something like:
public void display(FirstClass toDisplay) {
System.out.println(toDisplay.getFirst());
}
with:
public class FirstClass {
private int first;
public int getFirst() { return first };
The point is: you really do not want to directly expose fields of one class to other classes. Using a getter isn't so much better, but at least it gives you control about the fact that a "read access" took place.

Related

How to avoid creating object only referenced by inner class in Java?

I'm trying to create some system with inner class. My code can be summarized to something like this.
public abstract class A {
public abstract void doSomething();
}
public class B {
public final ArrayList<A> list=new ArrayList<A>();
public B(){
}
}
public class C {
private int i;
public C(B b){
b.list.add(new A(){
public void doSomething(){
i++;
}
});
b.list.add(new A(){
public void doSomething(){
System.out.println(i);
}
});
}
}
public static void main (String[] arg) {
B manager=new B();
new C(manager);
new C(manager);
new C(manager);
}
A is abstract class that will be inherited as inner class (in my original code it is listener class), B is some kind of manager class that hold list of As, and C hold data it's data should be only modified or read by it's inner class and upon initialization it add A to the class B. Code itself works fine. But problem is as there will be various kinds of C something like C2, C3 that does different thing and this leads to my code overwhelmed with thousands of unassigned object new C(manager); this make debugging extra hard and code looks really ugly. So it seems to me my approach in the first place was wrong but have no idea how to avoid this. So how should I change my approach to not have thousands of unassigned objects?
My suggestion is: try not to use constructors to do operations that depend on state (i). Use static functions, and save the state in a separate class (we call it a “context”).
import java.util.ArrayList;
public class Demo {
// A
abstract static class InnerListener {
public abstract void onEvent();
}
// B
static class ListenerManager {
public final ArrayList<InnerListener> listeners = new ArrayList<InnerListener>();
}
static class SideEffectContext {
public int i = 0;
}
// C
static class ListenerUtil {
public static void setupListeners(ListenerManager manager, SideEffectContext context) {
manager.listeners.add(new InnerListener() {
public void onEvent() {
context.i++;
}
});
manager.listeners.add(new InnerListener() {
public void onEvent() {
System.out.println(context.i);
}
});
}
}
public static void main(String[] arg) {
var manager = new ListenerManager();
var ctxA = new SideEffectContext();
var ctxShared = new SideEffectContext();
ListenerUtil.setupListeners(manager, ctxA);
ListenerUtil.setupListeners(manager, ctxShared);
ListenerUtil.setupListeners(manager, ctxShared);
}
}

Java visible interface that can not be implemented

I'm working on making a programming language that compiles to JVM bytecode, and it highly relies on interfaces as types. I need some way to make an interface private, but have other code still be able to access it, but not make something that implements it.
I was thinking about using abstract classes with a private constructor, so only the classes in the same file would be able to access it. The only problem is that it is impossible to extend multiple abstract classes at once. For example, the structure of a simple compiled program would be this:
// -> Main.java
public class Main {
public static MyInteger getMyInteger() {
return new MyIntegerImpl(10);
}
public static void main(String[] args) {}
private interface MyInteger {
public int getValue();
}
private static class MyIntegerImpl implements MyInteger {
private final int value;
public int getValue() {
return value;
}
public MyIntegerImpl(int value) {
this.value = value;
}
}
}
And another file, in which there is a problem:
// -> OtherFile.java
public class OtherFile {
public static void main(String[] args) {
Main.MyInteger myInteger = Main.getMyInteger(); //Error: The type Main.MyInteger is not visible.
System.out.println(myInteger.getValue());
}
//I do not want this to be allowed
public static class sneakyInteger implements Main.MyInteger { //Error(Which is good)
public int getValue() {
System.out.println("Person accessed value");
return 10;
}
}
}
The reason why I want to do this is so one person can not mess up any other person's code by providing their own implementations of things that should be only implemented by that other person.
Any help would be much appreciated.
I'm pretty sure that you should think again about what you are trying to do and change approach, but the answer for your question is to add to the interface some empty void method that is getting the parameter of the inner private class specific for the wrapper class
public class Test {
private class InnerPrivateClass {
private InnerPrivateClass() {}
}
public interface MyInteger {
int getValue();
void accept(InnerPrivateClass c);
}
private class MyIntegerImpl implements MyInteger {
#Override
public int getValue() {
return 0;
}
#Override
public void accept(InnerPrivateClass c) {}
}
}
However, as I said, I don't like this and for me it means that your idea is broken

java - can a class type parameter from a static main class be passed to another class

I have 2 classes the static main class and class B. I'm trying to pass main to B, where there is a method that sets fields.
Can this be done?
If so, could you please provide examples?
public static void main(String[] args) {
ArrayList a = new ArrayList()
class b = new class()
b.update(b);
}
class a {
public void update(ArrayList a) {
//updates the encapsulated arrayList field
}
}
The error message keeps on saying that one is static and the other is non-static, but they should be pointing the same object
I'm not entirely sure what you are trying to do, but here is an example that shows that you can pass an instance of the main class into another class:
public class A {
private String str = null;
public static void main(String[] args) {
A a = new A();
B b = new B(a);
System.out.println(a.getStr());
}
public String getStr() {
return this.str;
}
public void setStr(String str) {
this.str = str;
}
}
public class B {
public B(A a) {
a.setA("hello");
}
}
Running this code will print out hello.
main is static and public, so you can call it from any other class as any other public static method: statically.
if you have a class A that contains a
public static void main(String[] args)
method, then class B can call this method like
A.main(s);
where s is String[]
your question is far from clear, so I suggest you to add more code samples to make it clear what you're really trying to do.

How can I access a method of an "unnamed" class?

public class Test {
public static void main(String[] args) {
DemoAbstractClass abstractClass = new DemoAbstractClass() {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
};
abstractClass.runner();
/**
* I want to access getVal method here
*/
}
}
abstract class DemoAbstractClass {
public void run() {
System.out.println("running");
}
public abstract void runner();
}
Here, I'm declaring an abstract class DemoAbstractClass. I can obviously create a new class that extends this class and add this method to it. But, I would prefer not doing that in my scenario.
Is there any other way to access getVal method in above code??
You can't. You need to make a proper (non-anomous) class out of it. Make it an inner private class if you want to limit its scope.
Alternatively, you could use a StringBuffer and share a referense to it between the methods. Not extremely clean however.
Related question:
Accessing inner anonymous class members
Short of using reflection, you cannot as you have no access to the concrete type of the object to be able to bind the methodcall to
If you don want to do something like this in a sane manner, declare a named class and use that as the type of abstractClass
Unfortunately, if you cannot name the type, you cannot access the methods at the language level.
What you can do, though, is use the reflection API to get a Method object and invoke it on this object.
This, however, is pretty slow. A private class or private interface would be much faster.
I can obviously create a new class that extends this class and add this method to it.
You've already done this; the end result was an anonymous inner class: new DemoAbstractClass() { ... }; If you just moved that declaration into its own class -- you can even make it a private class -- you can access getVal.
Per your example above:
public class Test {
public static void main(String[] args) {
DemoClass abstractClass = new DemoClass();
abstractClass.runner();
/**
* I want to access getVal method here
*/
abstractClass.getVal(); // can do this here now
}
private class DemoClass extends DemoAbstractClass {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
}
}
}
Another option is to make a StringBuilder a member of the main method and use the closure nature of anonymous inner methods:
public static void main(String[] args) {
final StringBuilder value = new StringBuilder();
DemoAbstractClass abstractClass = new DemoAbstractClass() {
#Override
public void runner() {
value.append( "test" );
System.out.println(val);
this.run();
}
};
abstractClass.runner();
// use val here...
String val = value.toString();
}

Java: Parent Methods accessing Subclasses' static variables?

I am trying to understand my way around polymorphism in Java. I created a parent class that has too many common methods that all children will use in the same manner.
Each of the subclasses' children all share static information, These variables or information will be used in the methods declared only in the parent.
The problem wish accessing static variables from Parent methods seems not really possible,
Its a solution to declare the common information per instance but since there will be 1000s of instances its such a waste of memory.
A simple elaboration of what i mean is the following code :
class testParent {
static int k;
public void print()
{
System.out.println(k);
}
}
class testChild2 extends testParent
{
static
{
testChild2.k =2;
}
}
public class testChild1 extends testParent{
static
{
testChild1.k = 1;
}
public static void main(String[] args)
{
new testChild1().print();
new testChild2().print();
new testChild1().print();
}
}
the output i expect was
1
2
1.
but what happens is :
1
2
2
One might think that on the initiation of each subclass the static variables of this subclass is set and then all methods referring to this subclass has access to the corresponding 'k' value.
But what actually happens is that all subclasses edit in the same static variable that is shared along all subclasses and hence destroys my whole point of using static variables for each subclass and its instances and using commmon methods in the Parent accessing these variables.
Any idea how can this be done ?
An option is to access the subclasses' static data through an abstract (non-static) method:
abstract public class Parent {
protected abstract int getK();
public void print() {
System.out.println(getK());
}
}
public class Child1 extends Parent {
private static final int CHILD1_K = 1;
protected int getK() { return CHILD1_K; }
}
public class Child2 extends Parent {
private static final int CHILD2_K = 2;
protected int getK() { return CHILD2_K; }
}
When you make new testChild2().print(); the static block on testChield2 was executed and change the value to 2.
static blocks only execute once when loaded by the ClassLoader.
This one give the output you want:
class testParent {
static int k;
public void print()
{
System.out.println(k);
}
}
class testChild2 extends testParent
{
{
testChild2.k =2;
}
}
public class testChild1 extends testParent{
{
testChild1.k = 1;
}
public static void main(String[] args)
{
new testChild1().print();
new testChild2().print();
new testChild1().print();
}
}
Non static code blocks execute everytime the class is instanciated.
Premature optimization is the root of all evil. I don't think you'll run into any memory issues with thousands of instances, each with their own data, unless you're working on a tiny embedded system of some kind. Static variables are not intended to do what you're trying to do with them.
Static variables are specific to the class itself. If you want the same field in different instances of a class to have different values, then that field cannot be static.
The solution: don't make k static.
class testParent {
int k;
public void print()
{
System.out.println(k);
}
}
class testChild2 extends testParent
{
{
this.k =2;
}
}
class testChild1 extends testParent{
{
this.k = 1;
}
public static void main(String[] args){
new testChild1().print();
new testChild2().print();
new testChild1().print();
}
}
Demo
(ignore the static class business - that's just to make it work in ideone).

Categories